def set_power_state(self, session, target): """Run an action modifying this node's power state. This call is asynchronous, it will return success as soon as the Bare Metal service acknowledges the request. :param session: The session to use for making this request. :type session: :class:`~keystoneauth1.adapter.Adapter` :param target: Target power state, e.g. "rebooting", "power on". See the Bare Metal service documentation for available actions. """ session = self._get_session(session) if target.startswith("soft "): version = '1.27' else: version = None version = utils.pick_microversion(session, version) # TODO(dtantsur): server timeout support body = {'target': target} request = self._prepare_request(requires_id=True) request.url = utils.urljoin(request.url, 'states', 'power') response = session.put( request.url, json=body, headers=request.headers, microversion=version, retriable_status_codes=_common.RETRIABLE_STATUS_CODES) msg = ("Failed to set power state for bare metal node {node} " "to {target}".format(node=self.id, target=target)) exceptions.raise_from_response(response, error_message=msg)
def set_traits(self, session, traits): """Set traits for a node. Removes any existing traits and adds the traits passed in to this method. :param session: The session to use for making this request. :param traits: list of traits to add to the node. :returns: The updated :class:`~openstack.baremetal.v1.node.Node` """ session = self._get_session(session) version = utils.pick_microversion(session, '1.37') request = self._prepare_request(requires_id=True) request.url = utils.urljoin(request.url, 'traits') body = {'traits': traits} response = session.put( request.url, json=body, headers=request.headers, microversion=version, retriable_status_codes=_common.RETRIABLE_STATUS_CODES) msg = ("Failed to set traits for node {node}" .format(node=self.id)) exceptions.raise_from_response(response, error_message=msg) self.traits = traits
def remove_trait(self, session, trait, ignore_missing=True): """Remove a trait from a node. :param session: The session to use for making this request. :param trait: The trait to remove from the node. :param bool ignore_missing: When set to ``False`` :class:`~openstack.exceptions.ResourceNotFound` will be raised when the trait does not exist. Otherwise, ``False`` is returned. :returns: The updated :class:`~openstack.baremetal.v1.node.Node` """ session = self._get_session(session) version = utils.pick_microversion(session, '1.37') request = self._prepare_request(requires_id=True) request.url = utils.urljoin(request.url, 'traits', trait) response = session.delete( request.url, headers=request.headers, microversion=version, retriable_status_codes=_common.RETRIABLE_STATUS_CODES) if ignore_missing or response.status_code == 400: session.log.debug( 'Trait %(trait)s was already removed from node %(node)s', {'trait': trait, 'node': self.id}) return False msg = ("Failed to remove trait {trait} from bare metal node {node}" .format(node=self.id, trait=trait)) exceptions.raise_from_response(response, error_message=msg) self.traits = list(set(self.traits) - {trait}) return True
def patch(self, session, patch=None, prepend_key=True, has_body=True, retry_on_conflict=None, base_path=None, reset_interfaces=None): if reset_interfaces is not None: # The id cannot be dirty for an commit self._body._dirty.discard("id") # Only try to update if we actually have anything to commit. if not patch and not self.requires_commit: return self if not self.allow_patch: raise exceptions.MethodNotSupported(self, "patch") session = self._get_session(session) microversion = utils.pick_microversion(session, '1.45') params = [('reset_interfaces', reset_interfaces)] request = self._prepare_request(requires_id=True, prepend_key=prepend_key, base_path=base_path, patch=True, params=params) if patch: request.body += self._convert_patch(patch) return self._commit(session, request, 'PATCH', microversion, has_body=has_body, retry_on_conflict=retry_on_conflict) else: return super(Node, self).patch(session, patch=patch, retry_on_conflict=retry_on_conflict)
def add_trait(self, session, trait): """Add a trait to a node. :param session: The session to use for making this request. :param trait: The trait to add to the node. :returns: The updated :class:`~openstack.baremetal.v1.node.Node` """ session = self._get_session(session) version = utils.pick_microversion(session, '1.37') request = self._prepare_request(requires_id=True) request.url = utils.urljoin(request.url, 'traits', trait) response = session.put( request.url, json=None, headers=request.headers, microversion=version, retriable_status_codes=_common.RETRIABLE_STATUS_CODES) msg = ("Failed to add trait {trait} for node {node}" .format(trait=trait, node=self.id)) exceptions.raise_from_response(response, error_message=msg) self.traits = list(set(self.traits or ()) | {trait})
def set_provision_state(self, session, target, config_drive=None, clean_steps=None, rescue_password=None, wait=False, timeout=None): """Run an action modifying this node's provision state. This call is asynchronous, it will return success as soon as the Bare Metal service acknowledges the request. :param session: The session to use for making this request. :type session: :class:`~keystoneauth1.adapter.Adapter` :param target: Provisioning action, e.g. ``active``, ``provide``. See the Bare Metal service documentation for available actions. :param config_drive: Config drive to pass to the node, only valid for ``active` and ``rebuild`` targets. You can use functions from :mod:`openstack.baremetal.configdrive` to build it. :param clean_steps: Clean steps to execute, only valid for ``clean`` target. :param rescue_password: Password for the rescue operation, only valid for ``rescue`` target. :param wait: Whether to wait for the target state to be reached. :param timeout: Timeout (in seconds) to wait for the target state to be reached. If ``None``, wait without timeout. :return: This :class:`Node` instance. :raises: ValueError if ``config_drive``, ``clean_steps`` or ``rescue_password`` are provided with an invalid ``target``. """ session = self._get_session(session) if target in _common.PROVISIONING_VERSIONS: version = '1.%d' % _common.PROVISIONING_VERSIONS[target] else: if config_drive and target == 'rebuild': version = '1.35' else: version = None version = utils.pick_microversion(session, version) body = {'target': target} if config_drive: if target not in ('active', 'rebuild'): raise ValueError('Config drive can only be provided with ' '"active" and "rebuild" targets') # Not a typo - ironic accepts "configdrive" (without underscore) body['configdrive'] = config_drive if clean_steps is not None: if target != 'clean': raise ValueError('Clean steps can only be provided with ' '"clean" target') body['clean_steps'] = clean_steps if rescue_password is not None: if target != 'rescue': raise ValueError('Rescue password can only be provided with ' '"rescue" target') body['rescue_password'] = rescue_password if wait: try: expected_state = _common.EXPECTED_STATES[target] except KeyError: raise ValueError('For target %s the expected state is not ' 'known, cannot wait for it' % target) request = self._prepare_request(requires_id=True) request.url = utils.urljoin(request.url, 'states', 'provision') response = session.put( request.url, json=body, headers=request.headers, microversion=version, retriable_status_codes=_common.RETRIABLE_STATUS_CODES) msg = ("Failed to set provision state for bare metal node {node} " "to {target}".format(node=self.id, target=target)) exceptions.raise_from_response(response, error_message=msg) if wait: return self.wait_for_provision_state(session, expected_state, timeout=timeout) else: return self.fetch(session)
def set_provision_state(self, session, target, config_drive=None, clean_steps=None, rescue_password=None, wait=False, timeout=None): """Run an action modifying this node's provision state. This call is asynchronous, it will return success as soon as the Bare Metal service acknowledges the request. :param session: The session to use for making this request. :type session: :class:`~keystoneauth1.adapter.Adapter` :param target: Provisioning action, e.g. ``active``, ``provide``. See the Bare Metal service documentation for available actions. :param config_drive: Config drive to pass to the node, only valid for ``active` and ``rebuild`` targets. You can use functions from :mod:`openstack.baremetal.configdrive` to build it. :param clean_steps: Clean steps to execute, only valid for ``clean`` target. :param rescue_password: Password for the rescue operation, only valid for ``rescue`` target. :param wait: Whether to wait for the target state to be reached. :param timeout: Timeout (in seconds) to wait for the target state to be reached. If ``None``, wait without timeout. :return: This :class:`Node` instance. :raises: ValueError if ``config_drive``, ``clean_steps`` or ``rescue_password`` are provided with an invalid ``target``. """ session = self._get_session(session) version = None if target in _common.PROVISIONING_VERSIONS: version = '1.%d' % _common.PROVISIONING_VERSIONS[target] if config_drive: # Some config drive actions require a higher version. if isinstance(config_drive, dict): version = '1.56' elif target == 'rebuild': version = '1.35' version = utils.pick_microversion(session, version) body = {'target': target} if config_drive: if target not in ('active', 'rebuild'): raise ValueError('Config drive can only be provided with ' '"active" and "rebuild" targets') # Not a typo - ironic accepts "configdrive" (without underscore) body['configdrive'] = config_drive if clean_steps is not None: if target != 'clean': raise ValueError('Clean steps can only be provided with ' '"clean" target') body['clean_steps'] = clean_steps if rescue_password is not None: if target != 'rescue': raise ValueError('Rescue password can only be provided with ' '"rescue" target') body['rescue_password'] = rescue_password if wait: try: expected_state = _common.EXPECTED_STATES[target] except KeyError: raise ValueError('For target %s the expected state is not ' 'known, cannot wait for it' % target) request = self._prepare_request(requires_id=True) request.url = utils.urljoin(request.url, 'states', 'provision') response = session.put( request.url, json=body, headers=request.headers, microversion=version, retriable_status_codes=_common.RETRIABLE_STATUS_CODES) msg = ("Failed to set provision state for bare metal node {node} " "to {target}".format(node=self.id, target=target)) exceptions.raise_from_response(response, error_message=msg) if wait: return self.wait_for_provision_state(session, expected_state, timeout=timeout) else: return self.fetch(session)