def __iter__(s): center(s.__class__.__name__) s.__fetch_if_needed() for item in s.__tags: n = Tag(client=s.__maas).load_dict(item) yield n cleave(s.__class__.__name__)
def __iter__(s): center(s.__class__.__name__) s.__fetch_if_needed() for ptype in s.__power_types: n = PowerType(s.__maas, ptype) yield n cleave(s.__class__.__name__)
def __init__(s, maas, iface): center('Interface.__init__') s.__maas = maas dict.__init__(s, iface) cleave('Interface.__init__')
def __iter__(s): center(s.__class__.__name__) s.__fetch_if_needed() for item in s.__users: n = User().load_dict(item) yield n cleave(s.__class__.__name__)
def __init__(s, maas, image): center(s.__class__.__name__) s.__maas = maas dict.__init__(s, image) cleave(s.__class__.__name__)
def new(s, architecture, mac_addresses, autodetect_nodegroup=True, min_hwe_kernel=None, subarchitecture=None, hostname=None, power_type=None, nodegroup=None): center(s.__class__.__name__) data = [] data.append(('architecture', architecture)) data.append(('mac_addresses', mac_addresses)) data.append(('autodetect_nodegroup', autodetect_nodegroup)) if min_hwe_kernel: data.append(('min_hwe_kenrel', min_hwe_kernel)) if subarchitecture: data.append(('subarchitecture', subarchitecture)) if hostname: data.append(('hostname', hostname)) if power_type: data.append(('power_type', power_type)) if nodegroup: data.append(('nodegroup', nodegroup)) response = s.__maas.post(u'/nodes/', op='new', data=data) if not response.ok: if type(response.data) == str: cleave(s.__class__.__name__) raise MapiError(response.data) cleave(s.__class__.__name__) return response.data
def __init__(s, maas, op='list', uri=u'/nodes/'): center(s.__class__.__name__) s.__maas = maas s.__resources = None s.__op = op s.__uri = uri cleave(s.__class__.__name__)
def __iter__(s): center(s.__class__.__name__) s.__fetch_if_needed() for group in s.__resources: n = BootSource(s.__maas, group) yield n cleave(s.__class__.__name__)
def __getitem__(s, index): center(s.__class__.__name__) s.__fetch_if_needed() print(index) retval = Event(s.__maas, s.__events[index]) cleave(s.__class__.__name__) return retval
def __init__(s, client=None, name=None, comment=None, definition=None): center(s.__class__.__name__) s.__name = name s.__comment = comment s.__definition = definition s.__maas = client cleave(s.__class__.__name__)
def __iter__(s): center(s.__class__.__name__) s.__fetch_if_needed() for item in s.__zones: n = Zone(s.__maas, item) yield n cleave(s.__class__.__name__)
def __iter__(s): center(s.__class__.__name__) s.__fetch_if_needed() for item in s.__groups: n = VolumeGroup().load_dict(item) yield n cleave(s.__class__.__name__)
def __iter__(s): center(s.__class__.__name__) s.__fetch_if_needed() for group in s.__nodegroups: n = Nodegroup(s.__maas, group) yield n cleave(s.__class__.__name__)
def abort_operation(s): ''' ''' center(s.__class__.__name__) response = s.__maas.post(u'/nodes/%s/' % s['system_id'], op='abort_operation') return response
def call(cls, uri, op, method, creds, data=[]): center('RestClient.call') # TODO: this is el-cheapo URI Template # <http://tools.ietf.org/html/rfc6570> support; use uritemplate-py # <https://github.com/uri-templates/uritemplate-py> here? #uri = self.uri.format(**vars(options)) # Bundle things up ready to throw over the wire. uri, body, headers = cls.prepare_payload(op, method, uri, data) # Headers are returned as a list, but they must be a dict for # the signing machinery. headers = dict(headers) # Sign request if credentials have been provided. credentials = creds.split(':') if credentials is not None: cls.sign(uri, headers, credentials) # Use httplib2 instead of urllib2 (or MAASDispatcher, which is based # on urllib2) so that we get full control over HTTP method. TODO: # create custom MAASDispatcher to use httplib2 so that MAASClient can # be used. response, content = http_request(uri, method, body=body, headers=headers, insecure=False) # Compare API hashes to see if our version of the API is old. #self.compare_api_hashes(self.profile, response) # Output. #cdebug('response.status: %d' % response.status) #cls.print_debug(response) #cls.print_response(response, content) # 2xx status codes are all okay. if response.status // 100 != 2: cleave('MaiClient.call') if response.status == 500: raise MaasApiHttpInternalServerError(response.status, content) elif response.status == 503: raise MaasApiHttpServiceUnavailable(response.status, content) elif response.status == 400: raise MaasApiHttpBadRequest(response.status, content) elif response.status == 409: raise MaasApiHttpConflict(response.status, content) else: raise MaasApiUnknownError(response.status, content) if is_response_textual(response): try: retval = Response(True, json.loads(content)) if Clog.dbg: cdebug('content: %s' % content) except ValueError: # The content is not a json string. Just assume it's a plain string. # retval = Response(True, content) else: retval = Response(True, content) cleave('RestClient.call') return retval
def __init__(s, node, system_id): center(s.__class__.__name__) s.__node = node s.__maas = node.client s.__system_id = system_id s.__groups = None cleave(s.__class__.__name__)
def __init__(s, url, creds): center(s.__class__.__name__) cdebug(' url: %s' % url) cdebug(' creds: %s' % creds) s.root = url s.creds = creds cleave(s.__class__.__name__)
def name_value_pair(string): """Ensure that `string` is a valid ``name:value`` pair. When `string` is of the form ``name=value``, this returns a 2-tuple of ``name, value``. However, when `string` is of the form ``name@=value``, this returns a ``name, opener`` tuple, where ``opener`` is a function that will return an open file handle when called. The file will be opened in binary mode for reading only. """ center('RestClient.name_value_pair') parts = re.split(r'(=|@=)', string, 1) if len(parts) == 3: name, what, value = parts if what == "=": cleave('RestClient.name_value_pair (%s : %s)' % (name, value)) return name, value elif what == "@=": cleave('RestClient.name_value_pair') return name, partial(open, value, "rb") else: cleave('RestClient.name_value_pair') raise AssertionError( "Unrecognised separator %r" % what) else: cleave('RestClient.name_value_pair') raise CommandError( "%r is not a name=value or name@=filename pair" % string)
def power_types(s): center(s.__class__.__name__) retval = PowerTypes(s.__maas) cleave(s.__class__.__name__) return retval
def compare_api_hashes(profile, response): """Compare the local and remote API hashes. If they differ -- or the remote side reports a hash and there is no hash stored locally -- then show a warning to the user. """ center('RestClient.compare_api_hashes') hash_from_response = response.get("X-MAAS-API-Hash".lower()) if hash_from_response is not None: hash_from_profile = profile["description"].get("hash") if hash_from_profile != hash_from_response: warning = dedent("""\ WARNING! The API on the server differs from the description that is cached locally. This may result in failed API calls. Refresh the local API description with `maas refresh`. """) warning_lines = wrap(warning, width=70, initial_indent="*** ", subsequent_indent="*** ") print("**********" * 7, file=sys.stderr) for warning_line in warning_lines: print(warning_line, file=sys.stderr) print("**********" * 7, file=sys.stderr) cleave('RestClient.compare_api_hashes')
def name_value_pair(string): """Ensure that `string` is a valid ``name:value`` pair. When `string` is of the form ``name=value``, this returns a 2-tuple of ``name, value``. However, when `string` is of the form ``name@=value``, this returns a ``name, opener`` tuple, where ``opener`` is a function that will return an open file handle when called. The file will be opened in binary mode for reading only. """ center('RestClient.name_value_pair') parts = re.split(r'(=|@=)', string, 1) if len(parts) == 3: name, what, value = parts if what == "=": cleave('RestClient.name_value_pair (%s : %s)' % (name, value)) return name, value elif what == "@=": cleave('RestClient.name_value_pair') return name, partial(open, value, "rb") else: cleave('RestClient.name_value_pair') raise AssertionError("Unrecognised separator %r" % what) else: cleave('RestClient.name_value_pair') raise CommandError( "%r is not a name=value or name@=filename pair" % string)
def details(s): ''' A collection of detailed information about all of the nodes in a particular nodegroup. ''' center(s.__class__.__name__) #from client import MCA # Will probably produce a Nodes object but for now just return what comes # back from the rest interface. # response = s.__maas.post(u'/nodegroups/%s/' % s['uuid'], op='details') if not response.ok: if type(response.data) == str: cleave(s.__class__.__name__) raise MapiError(response.data) data = bson.BSON.decode(response.data) cdebug(json.dumps(data, sort_keys=True, indent=4)) retval = response.data cleave(s.__class__.__name__) return retval
def __iter__(s): center('Interfaces.__iter__') s.__fetch_if_needed() for iface in s.__interfaces: n = Interface(s.__maas, iface) yield n cleave('Interfaces.__iter__')
def load_dict(s, d): center(s.__class__.__name__) s.__name = d.get('name', None) s.__comment = d.get('comment', None) s.__definition = d.get('definition', None) cleave(s.__class__.__name__) return s
def __iter__(s): center(s.__class__.__name__) s.__fetch_if_needed() for ptype in s.__boot_images: n = BootImage(s.__maas, ptype) yield n cleave(s.__class__.__name__)
def __init__(s, username=None, password=None, email=None, superuser=False): center(s.__class__.__name__) s.__username = username s.__email = email s.__password = password s.__superuser = superuser cleave(s.__class__.__name__)
def __iter__(s): center(s.__class__.__name__) s.__fetch_if_needed() for item in s.__events: s.__item_index += 1 n = Event(s.__maas, item) yield n cleave(s.__class__.__name__)
def details(s): ''' ''' center(s.__class__.__name__) response = s.__maas.get(u'/nodes/%s/' % s['system_id'], op='details') retval = response.data cleave(s.__class__.__name__) return retval
def __init__(s, maas, group): center('Nodegroup.__init__') s.__maas = maas cdebug('group: %s' % group) dict.__init__(s, group) cleave('Nodegroup.__init__')
def is_response_textual(response): """Is the response body text?""" center('api.is_response_textual') content_type = get_response_content_type(response) cdebug('content_type: %s' % content_type) retval = (content_type.endswith("/json") or content_type.startswith("text/")) cleave('api.is_response_textual (%s)' % retval) return retval
def mark_broken(s, description=None): center(s.__class__.__name__) data = [] if description: data.append( ('description', description) ) retval = s._op(u'/nodes/%s/' % s['system_id'], op='mark_broken', data=data) cleave(s.__class__.__name__) return retval
def __init__(s, maas, name=None, uuid=None, block_devices=None, partitions=None): center(s.__class__.__name__) s.__maas = maas s.__name = name s.__uuid = uuid s.__block_devices = block_devices s.__partitions = partitions cleave(s.__class__.__name__)
def __delitem__(s, key): center(s.__class__.__name__) response = s.__maas.delete(u'/account/prefs/sslkeys/%s/' % s.__keys[key]['id']) if not response.ok: if type(response.data) == str: cleave(s.__class__.__name__) raise MapiError(response.data) s.__keys = None cleave(s.__class__.__name__)
def __delitem__(s, key): center(s.__class__.__name__) response = s.__maas.delete(u'/zones/%s/' % key) if not response.ok: if type(response.data) == str: cleave(s.__class__.__name__) raise MapiError(response.data) s.__zones = None cleave(s.__class__.__name__)
def delete(s): center(s.__class__.__name__) response = s.__maas.delete(u'/tags/%s/' % s.name, op='delete') if not response.ok: if type(response.data) == str: cleave(s.__class__.__name__) raise MapiError(response.data) cleave(s.__class__.__name__) return response.data
def rebuild(s): center(s.__class__.__name__) response = s.__maas.post(u'/tags/%s/' % s.name, op='rebuild') if not response.ok: if type(response.data) == str: cleave(s.__class__.__name__) raise MapiError(response.data) cleave(s.__class__.__name__) return response.data
def __init__(s, obj): center(s.__class__.__name__) if type(obj) != dict: raise TypeError, "Object is of type %s but must be of type dict." % type(obj) for k in obj: setattr(s, k, obj[k]) cleave(s.__class__.__name__)