# Copyright 2013 VMware, Inc # # 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 base64 from oslo_serialization import jsonutils import requests import six from vmware_nsx.plugins.nsx_v.vshield.common import exceptions def _xmldump(obj): """Sort of improved xml creation method. This converts the dict to xml with following assumptions: Keys starting with _(underscore) are to be used as attributes and not element keys starting with @ so that dict can be made. Keys starting with __(double underscore) are to be skipped and its value is processed. The keys are not part of any xml schema. """ config = "" attr = "" if isinstance(obj, dict): for key, value in six.iteritems(obj): if key.startswith('__'): # Skip the key and evaluate it's value. a, x = _xmldump(value) config += x elif key.startswith('_'): attr += ' %s="%s"' % (key[1:], value) else: a, x = _xmldump(value) if key.startswith('@'): cfg = "%s" % (x) else: cfg = "<%s%s>%s" % (key, a, x, key) config += cfg elif isinstance(obj, list): for value in obj: a, x = _xmldump(value) attr += a config += x else: config = obj return attr, config def xmldumps(obj): attr, xml = _xmldump(obj) return xml class VcnsApiHelper(object): errors = { 303: exceptions.ResourceRedirect, 400: exceptions.RequestBad, 403: exceptions.Forbidden, 404: exceptions.ResourceNotFound, 409: exceptions.ServiceConflict, 415: exceptions.MediaTypeUnsupport, 503: exceptions.ServiceUnavailable } def __init__(self, address, user, password, format='json', ca_file=None, insecure=True): self.authToken = base64.encodestring(six.b("%s:%s" % (user, password))) self.user = user self.passwd = password self.address = address self.format = format if format == 'json': self.encode = jsonutils.dumps else: self.encode = xmldumps if insecure: self.verify_cert = False else: if ca_file: self.verify_cert = ca_file else: self.verify_cert = True def request(self, method, uri, params=None, headers=None, encodeparams=True): uri = self.address + uri if headers is None: headers = {} headers['Accept'] = 'application/' + self.format headers['Authorization'] = 'Basic ' + self.authToken.strip() headers['Content-Type'] = 'application/' + self.format if params: if encodeparams is True: data = self.encode(params) else: data = params else: data = None response = requests.request(method, uri, verify=self.verify_cert, data=data, headers=headers) status = response.status_code if 200 <= status < 300: return response.headers, response.text if status in self.errors: cls = self.errors[status] else: cls = exceptions.VcnsApiException raise cls(uri=uri, status=status, header=response.headers, response=response.text)