manila/manila/share/drivers/dell_emc/common/enas/xml_api_parser.py

318 lines
9.7 KiB
Python

# Copyright (c) 2016 Dell Inc. or its subsidiaries.
# All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License"); you may
# not use this file except in compliance with the License. You may obtain
# a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
# License for the specific language governing permissions and limitations
# under the License.
import io
import re
from lxml import etree
class XMLAPIParser(object):
def __init__(self):
# The following Boolean acts as the flag for the common sub-element.
# For instance:
# <CifsServers>
# <li> server_1 </li>
# </CifsServers>
# <Alias>
# <li> interface_1 </li>
# </Alias>
self.is_QueryStatus = False
self.is_CifsServers = False
self.is_Aliases = False
self.is_MoverStatus = False
self.is_TaskResponse = False
self.is_Vdm = False
self.is_Interfaces = False
self.elt = {}
def _remove_ns(self, tag):
i = tag.find('}')
if i >= 0:
tag = tag[i + 1:]
return tag
def parse(self, xml):
result = {
'type': None,
'taskId': None,
'maxSeverity': None,
'objects': [],
'problems': [],
}
events = ("start", "end")
context = etree.iterparse(io.BytesIO(xml),
events=events)
for action, elem in context:
self.tag = self._remove_ns(elem.tag)
func = self._get_func(action, self.tag)
if func in vars(XMLAPIParser):
if action == 'start':
eval('self.' + func)(elem, result)
elif action == 'end':
eval('self.' + func)()
return result
def _get_func(self, action, tag):
if tag == 'W2KServerData':
return action + '_' + 'w2k_server_data'
temp_list = re.sub(r"([A-Z])", r" \1", tag).split()
if temp_list:
func_name = action + '_' + '_'.join(temp_list)
else:
func_name = action + '_' + tag
return func_name.lower()
def _copy_property(self, source, target, property, list_property=None):
for key in property:
if key in source:
target[key] = source[key]
if list_property:
for key in list_property:
if key in source:
target[key] = source[key].split()
def _append_elm_property(self, elm, result, property, identifier):
for obj in result['objects']:
if (identifier in obj and identifier in elm.attrib and
elm.attrib[identifier] == obj[identifier]):
for key, value in elm.attrib.items():
if key in property:
obj[key] = value
def _append_element(self, elm, result, property, list_property,
identifier):
sub_elm = {}
self._copy_property(elm.attrib, sub_elm, property, list_property)
for obj in result['objects']:
if (identifier in obj and identifier in elm.attrib and
elm.attrib[identifier] == obj[identifier]):
if self.tag in obj:
obj[self.tag].append(sub_elm)
else:
obj[self.tag] = [sub_elm]
def start_task_response(self, elm, result):
self.is_TaskResponse = True
result['type'] = 'TaskResponse'
self._copy_property(elm.attrib, result, ['taskId'])
def end_task_response(self):
self.is_TaskResponse = False
def start_fault(self, elm, result):
result['type'] = 'Fault'
def start_status(self, elm, result):
if self.is_TaskResponse:
result['maxSeverity'] = elm.attrib['maxSeverity']
elif self.is_MoverStatus or self.is_Vdm:
self.elt['maxSeverity'] = elm.attrib['maxSeverity']
def start_query_status(self, elm, result):
self.is_QueryStatus = True
result['type'] = 'QueryStatus'
self._copy_property(elm.attrib, result, ['maxSeverity'])
def end_query_status(self):
self.is_QueryStatus = False
def start_problem(self, elm, result):
self.elt = {}
properties = ('message', 'messageCode')
self._copy_property(elm.attrib, self.elt, properties)
result['problems'].append(self.elt)
def start_description(self, elm, result):
self.elt['Description'] = elm.text
def start_action(self, elm, result):
self.elt['Action'] = elm.text
def start_diagnostics(self, elm, result):
self.elt['Diagnostics'] = elm.text
def start_file_system(self, elm, result):
self.elt = {}
property = (
'fileSystem',
'name',
'type',
'storages',
'volume',
'dataServicePolicies',
'internalUse',
)
list_property = ('storagePools',)
self._copy_property(elm.attrib, self.elt, property, list_property)
result['objects'].append(self.elt)
def start_file_system_capacity_info(self, elm, result):
property = ('volumeSize',)
identifier = 'fileSystem'
self._append_elm_property(elm, result, property, identifier)
def start_storage_pool(self, elm, result):
self.elt = {}
property = ('name', 'autoSize', 'usedSize', 'diskType', 'pool',
'dataServicePolicies', 'virtualProvisioning')
list_property = ('movers',)
self._copy_property(elm.attrib, self.elt, property, list_property)
result['objects'].append(self.elt)
def start_system_storage_pool_data(self, elm, result):
property = ('greedy', 'isBackendPool')
self._copy_property(elm.attrib, self.elt, property)
def start_mover(self, elm, result):
self.elt = {}
property = ('name', 'host', 'mover', 'role')
list_property = ('ntpServers', 'standbyFors', 'standbys')
self._copy_property(elm.attrib, self.elt, property, list_property)
result['objects'].append(self.elt)
def start_mover_status(self, elm, result):
self.is_MoverStatus = True
property = ('version', 'csTime', 'clock', 'timezone', 'uptime')
identifier = 'mover'
self._append_elm_property(elm, result, property, identifier)
def end_mover_status(self):
self.is_MoverStatus = False
def start_mover_dns_domain(self, elm, result):
property = ('name', 'protocol')
list_property = ('servers',)
identifier = 'mover'
self._append_element(elm, result, property, list_property, identifier)
def start_mover_interface(self, elm, result):
property = (
'name',
'device',
'up',
'ipVersion',
'netMask',
'ipAddress',
'vlanid',
)
identifier = 'mover'
self._append_element(elm, result, property, None, identifier)
def start_logical_network_device(self, elm, result):
property = ('name', 'type', 'speed')
list_property = ('interfaces',)
identifier = 'mover'
self._append_element(elm, result, property, list_property, identifier)
def start_vdm(self, elm, result):
self.is_Vdm = True
self.elt = {}
property = ('name', 'state', 'mover', 'vdm')
self._copy_property(elm.attrib, self.elt, property)
result['objects'].append(self.elt)
def end_vdm(self):
self.is_Vdm = False
def start_interfaces(self, elm, result):
self.is_Interfaces = True
self.elt['Interfaces'] = []
def end_interfaces(self):
self.is_Interfaces = False
def start_li(self, elm, result):
if self.is_CifsServers:
self.elt['CifsServers'].append(elm.text)
elif self.is_Aliases:
self.elt['Aliases'].append(elm.text)
elif self.is_Interfaces:
self.elt['Interfaces'].append(elm.text)
def start_cifs_server(self, elm, result):
self.elt = {}
property = ('type', 'localUsers', 'name', 'mover', 'moverIdIsVdm')
list_property = ('interfaces',)
self._copy_property(elm.attrib, self.elt, property, list_property)
result['objects'].append(self.elt)
def start_aliases(self, elm, result):
self.is_Aliases = True
self.elt['Aliases'] = []
def end_aliases(self):
self.is_Aliases = False
def start_w2k_server_data(self, elm, result):
property = ('domain', 'compName', 'domainJoined')
self._copy_property(elm.attrib, self.elt, property)
def start_cifs_share(self, elm, result):
self.elt = {}
property = ('path', 'fileSystem', 'name', 'mover', 'moverIdIsVdm')
self._copy_property(elm.attrib, self.elt, property)
result['objects'].append(self.elt)
def start_cifs_servers(self, elm, result):
self.is_CifsServers = True
self.elt['CifsServers'] = []
def end_cifs_servers(self):
self.is_CifsServers = False
def start_checkpoint(self, elm, result):
self.elt = {}
property = ('checkpointOf', 'name', 'checkpoint', 'state')
self._copy_property(elm.attrib, self.elt, property)
result['objects'].append(self.elt)
def start_mount(self, elm, result):
self.elt = {}
property = ('fileSystem', 'path', 'mover', 'moverIdIsVdm')
self._copy_property(elm.attrib, self.elt, property)
result['objects'].append(self.elt)