Instruction:
Given the following Python 3 function, write the documentation
def get(self, name):
        self.auto_invalidate()
        try:
            return self._uris[name]
        except KeyError:
            self.refresh()
            try:
                return self._uris[name]
            except KeyError:
                raise NotFound({self._manager._name_prop: name}, self._manager)

Response: Get the resource URI for a specified resource name.


Instruction:
Can you tell what is the following Python 3 function doing
def auto_invalidate(self):
        current = datetime.now()
        if current > self._invalidated + timedelta(seconds=self._timetolive):
            self.invalidate()

Response: Invalidate the cache if the current time is past the time to live.


Instruction:
Create a Python 3 function for
refreshing the Name - URI cache from the HMC.

Response:
def refresh(self):
        """
        Refresh the Name-URI cache from the HMC.

        This is done by invalidating the cache, listing the resources of this
        manager from the HMC, and populating the cache with that information.
        """
        self.invalidate()
        full = not self._manager._list_has_name
        res_list = self._manager.list(full_properties=full)
        self.update_from(res_list)


Instruction:
Write a Python 3 function that can
update the Name - URI cache from the provided list of resources.

Response:
def update_from(self, res_list):
        """
        Update the Name-URI cache from the provided resource list.

        This is done by going through the resource list and updating any cache
        entries for non-empty resource names in that list. Other cache entries
        remain unchanged.
        """
        for res in res_list:
            # We access the properties dictionary, in order to make sure
            # we don't drive additional HMC interactions.
            name = res.properties.get(self._manager._name_prop, None)
            uri = res.properties.get(self._manager._uri_prop, None)
            self.update(name, uri)


Instruction:
Explain what the following Python 3 code does
def _try_optimized_lookup(self, filter_args):
        if filter_args is None or len(filter_args) != 1 or \
                self._oid_prop not in filter_args:
            return None

        oid_match = filter_args[self._oid_prop]
        if not isinstance(oid_match, six.string_types) or \
                not re.match(r'^[a-zA-Z0-9_\-]+$', oid_match):
            return None

        # The match string is a plain string (not a reg.expression)

        # Construct the resource URI from the filter property
        # and issue a Get <Resource> Properties on that URI
        uri = self._base_uri + '/' + oid_match

        try:
            props = self.session.get(uri)
        except HTTPError as exc:
            if exc.http_status == 404 and exc.reason == 1:
                # No such resource
                return None
            raise

        resource_obj = self.resource_class(
            manager=self,
            uri=props[self._uri_prop],
            name=props.get(self._name_prop, None),
            properties=props)

        resource_obj._full_properties = True

        return resource_obj

Response: Try to optimize the lookup by making a Get Properties operation on that URI.


Instruction:
Implement a function in Python 3 to
divide the filter arguments into a query parameter string and the remaining client - side filters.

Response:
def _divide_filter_args(self, filter_args):
        """
        Divide the filter arguments into filter query parameters for filtering
        on the server side, and the remaining client-side filters.

        Parameters:

          filter_args (dict):
            Filter arguments that narrow the list of returned resources to
            those that match the specified filter arguments. For details, see
            :ref:`Filtering`.

            `None` causes no filtering to happen, i.e. all resources are
            returned.

        Returns:

          : tuple (query_parms_str, client_filter_args)
        """
        query_parms = []  # query parameter strings
        client_filter_args = {}

        if filter_args is not None:
            for prop_name in filter_args:
                prop_match = filter_args[prop_name]
                if prop_name in self._query_props:
                    self._append_query_parms(query_parms, prop_name,
                                             prop_match)
                else:
                    client_filter_args[prop_name] = prop_match
        query_parms_str = '&'.join(query_parms)
        if query_parms_str:
            query_parms_str = '?{}'.format(query_parms_str)

        return query_parms_str, client_filter_args


Instruction:
Here you have a function in Python 3, explain what it does
def _matches_filters(self, obj, filter_args):
        if filter_args is not None:
            for prop_name in filter_args:
                prop_match = filter_args[prop_name]
                if not self._matches_prop(obj, prop_name, prop_match):
                    return False
        return True

Response: Returns a boolean indicating whether a resource object matches a set of filter arguments.


Instruction:
Here you have a function in Python 3, explain what it does
def _matches_prop(self, obj, prop_name, prop_match):
        if isinstance(prop_match, (list, tuple)):
            # List items are logically ORed, so one matching item suffices.
            for pm in prop_match:
                if self._matches_prop(obj, prop_name, pm):
                    return True
        else:
            # Some lists of resources do not have all properties, for example
            # Hipersocket adapters do not have a "card-location" property.
            # If a filter property does not exist on a resource, the resource
            # does not match.
            try:
                prop_value = obj.get_property(prop_name)
            except KeyError:
                return False
            if isinstance(prop_value, six.string_types):
                # HMC resource property is Enum String or (non-enum) String,
                # and is both matched by regexp matching. Ideally, regexp
                # matching should only be done for non-enum strings, but
                # distinguishing them is not possible given that the client
                # has no knowledge about the properties.

                # The regexp matching implemented in the HMC requires begin and
                # end of the string value to match, even if the '^' for begin
                # and '$' for end are not specified in the pattern. The code
                # here is consistent with that: We add end matching to the
                # pattern, and begin matching is done by re.match()
                # automatically.
                re_match = prop_match + '$'
                m = re.match(re_match, prop_value)
                if m:
                    return True
            else:
                if prop_value == prop_match:
                    return True
        return False

Response: Returns a boolean indicating whether a resource object matches the specified property and the match value.


Instruction:
How would you explain what the following Python 3 function does
def resource_object(self, uri_or_oid, props=None):
        if uri_or_oid.startswith('/api/'):
            assert uri_or_oid[-1] != '/'
            uri = uri_or_oid
            oid = uri.split('/')[-1]
        else:
            assert '/' not in uri_or_oid
            oid = uri_or_oid
            uri = '{}/{}'.format(self._base_uri, oid)
        res_props = {
            self._oid_prop: oid,
            'parent': self.parent.uri if self.parent is not None else None,
            'class': self.class_name,
        }
        name = None
        if props:
            res_props.update(props)
            try:
                name = props[self._name_prop]
            except KeyError:
                pass
        return self.resource_class(self, uri, name, res_props)

Response: Returns a minimalistic Python resource object for this resource class.


Instruction:
How would you explain what the following Python 3 function does
def findall(self, **filter_args):
        if len(filter_args) == 1 and self._name_prop in filter_args:
            try:
                obj = self.find_by_name(filter_args[self._name_prop])
            except NotFound:
                return []
            return [obj]
        else:
            obj_list = self.list(filter_args=filter_args)
            return obj_list

Response: Find all resources in scope of this manager and return a list of their Python resource objects.


Instruction:
Here you have a function in Python 3, explain what it does
def find(self, **filter_args):
        obj_list = self.findall(**filter_args)
        num_objs = len(obj_list)
        if num_objs == 0:
            raise NotFound(filter_args, self)
        elif num_objs > 1:
            raise NoUniqueMatch(filter_args, self, obj_list)
        else:
            return obj_list[0]

Response: Find exactly one resource in scope of this manager object by matching the specified filter arguments and return the corresponding Python resource object.


Instruction:
Make a summary of the following Python 3 code
def find_by_name(self, name):
        uri = self._name_uri_cache.get(name)
        obj = self.resource_class(
            manager=self,
            uri=uri,
            name=name,
            properties=None)
        return obj

Response: Finds a resource by its name and returns its Python resource object.


Instruction:
Here you have a function in Python 3, explain what it does
def add_resources(self, resources):
        for child_attr in resources:
            child_list = resources[child_attr]
            self._process_child_list(self, child_attr, child_list)

Response: Add faked child resources to this resource.


Instruction:
Can you implement a function in Python 3 that
adds a faked resource to this manager.

Response:
def add(self, properties):
        """
        Add a faked resource to this manager.

        For URI-based lookup, the resource is also added to the faked HMC.

        Parameters:

          properties (dict):
            Resource properties. If the URI property (e.g. 'object-uri') or the
            object ID property (e.g. 'object-id') are not specified, they
            will be auto-generated.

        Returns:
          FakedBaseResource: The faked resource object.
        """
        resource = self.resource_class(self, properties)
        self._resources[resource.oid] = resource
        self._hmc.all_resources[resource.uri] = resource
        return resource


Instruction:
How would you explain what the following Python 3 function does
def remove(self, oid):
        uri = self._resources[oid].uri
        del self._resources[oid]
        del self._hmc.all_resources[uri]

Response: Removes a faked resource from this manager.


Instruction:
Here you have a function in Python 3, explain what it does
def list(self, filter_args=None):
        res = list()
        for oid in self._resources:
            resource = self._resources[oid]
            if self._matches_filters(resource, filter_args):
                res.append(resource)
        return res

Response: Returns a list of all the faked resources of this manager.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def console(self):
        if self._console is None:
            self._console = self.list()[0]
        return self._console

Response: Returns the faked Console object.


Instruction:
Create a Python 3 function for
adding a faked HBA resource.

Response:
def add(self, properties):
        """
        Add a faked HBA resource.

        Parameters:

          properties (dict):
            Resource properties.

            Special handling and requirements for certain properties:

            * 'element-id' will be auto-generated with a unique value across
              all instances of this resource type, if not specified.
            * 'element-uri' will be auto-generated based upon the element ID,
              if not specified.
            * 'class' will be auto-generated to 'hba',
              if not specified.
            * 'adapter-port-uri' identifies the backing FCP port for this HBA
              and is required to be specified.
            * 'device-number' will be auto-generated with a unique value
              within the partition in the range 0x8000 to 0xFFFF, if not
              specified.

            This method also updates the 'hba-uris' property in the parent
            faked Partition resource, by adding the URI for the faked HBA
            resource.

        Returns:
          :class:`~zhmcclient_mock.FakedHba`: The faked HBA resource.

        Raises:
          :exc:`zhmcclient_mock.InputError`: Some issue with the input
            properties.
        """
        new_hba = super(FakedHbaManager, self).add(properties)

        partition = self.parent

        # Reflect the new NIC in the partition
        assert 'hba-uris' in partition.properties
        partition.properties['hba-uris'].append(new_hba.uri)

        # Create a default device-number if not specified
        if 'device-number' not in new_hba.properties:
            devno = partition.devno_alloc()
            new_hba.properties['device-number'] = devno

        # Create a default wwpn if not specified
        if 'wwpn' not in new_hba.properties:
            wwpn = partition.wwpn_alloc()
            new_hba.properties['wwpn'] = wwpn

        return new_hba


Instruction:
Can you generate the documentation for the following Python 3 function
def remove(self, oid):
        hba = self.lookup_by_oid(oid)
        partition = self.parent
        devno = hba.properties.get('device-number', None)
        if devno:
            partition.devno_free_if_allocated(devno)
        wwpn = hba.properties.get('wwpn', None)
        if wwpn:
            partition.wwpn_free_if_allocated(wwpn)
        assert 'hba-uris' in partition.properties
        hba_uris = partition.properties['hba-uris']
        hba_uris.remove(hba.uri)
        super(FakedHbaManager, self).remove(oid)

Response: Removes a faked HBA resource.


Instruction:
Can you implement a function in Python 3 that
adds a faked NIC resource.

Response:
def add(self, properties):
        """
        Add a faked NIC resource.

        Parameters:

          properties (dict):
            Resource properties.

            Special handling and requirements for certain properties:

            * 'element-id' will be auto-generated with a unique value across
              all instances of this resource type, if not specified.
            * 'element-uri' will be auto-generated based upon the element ID,
              if not specified.
            * 'class' will be auto-generated to 'nic',
              if not specified.
            * Either 'network-adapter-port-uri' (for backing ROCE adapters) or
              'virtual-switch-uri'(for backing OSA or Hipersockets adapters) is
              required to be specified.
            * 'device-number' will be auto-generated with a unique value
              within the partition in the range 0x8000 to 0xFFFF, if not
              specified.

            This method also updates the 'nic-uris' property in the parent
            faked Partition resource, by adding the URI for the faked NIC
            resource.

            This method also updates the 'connected-vnic-uris' property in the
            virtual switch referenced by 'virtual-switch-uri' property,
            and sets it to the URI of the faked NIC resource.

        Returns:
          :class:`zhmcclient_mock.FakedNic`: The faked NIC resource.

        Raises:
          :exc:`zhmcclient_mock.InputError`: Some issue with the input
            properties.
        """
        new_nic = super(FakedNicManager, self).add(properties)

        partition = self.parent

        # For OSA-backed NICs, reflect the new NIC in the virtual switch
        if 'virtual-switch-uri' in new_nic.properties:
            vswitch_uri = new_nic.properties['virtual-switch-uri']
            # Even though the URI handler when calling this method ensures that
            # the vswitch exists, this method can be called by the user as
            # well, so we have to handle the possibility that it does not
            # exist:
            try:
                vswitch = self.hmc.lookup_by_uri(vswitch_uri)
            except KeyError:
                raise InputError("The virtual switch specified in the "
                                 "'virtual-switch-uri' property does not "
                                 "exist: {!r}".format(vswitch_uri))
            connected_uris = vswitch.properties['connected-vnic-uris']
            if new_nic.uri not in connected_uris:
                connected_uris.append(new_nic.uri)

        # Create a default device-number if not specified
        if 'device-number' not in new_nic.properties:
            devno = partition.devno_alloc()
            new_nic.properties['device-number'] = devno

        # Reflect the new NIC in the partition
        assert 'nic-uris' in partition.properties
        partition.properties['nic-uris'].append(new_nic.uri)

        return new_nic


Instruction:
Given the following Python 3 function, write the documentation
def remove(self, oid):
        nic = self.lookup_by_oid(oid)
        partition = self.parent
        devno = nic.properties.get('device-number', None)
        if devno:
            partition.devno_free_if_allocated(devno)
        assert 'nic-uris' in partition.properties
        nic_uris = partition.properties['nic-uris']
        nic_uris.remove(nic.uri)
        super(FakedNicManager, self).remove(oid)

Response: Removes a faked NIC resource.


Instruction:
Can you create a Python 3 function that
allocates a device number unique to this partition in the range of 0x8000 to 0xFFFF.

Response:
def devno_alloc(self):
        """
        Allocates a device number unique to this partition, in the range of
        0x8000 to 0xFFFF.

        Returns:
          string: The device number as four hexadecimal digits in upper case.

        Raises:
          ValueError: No more device numbers available in that range.
        """
        devno_int = self._devno_pool.alloc()
        devno = "{:04X}".format(devno_int)
        return devno


Instruction:
Can you tell what is the following Python 3 function doing
def devno_free(self, devno):
        devno_int = int(devno, 16)
        self._devno_pool.free(devno_int)

Response: Free a device number allocated with devno_alloc.


Instruction:
Can you generate the documentation for the following Python 3 function
def devno_free_if_allocated(self, devno):
        devno_int = int(devno, 16)
        self._devno_pool.free_if_allocated(devno_int)

Response: Free a device number allocated with devno_alloc.


Instruction:
Can you tell what is the following Python 3 function doing
def wwpn_alloc(self):
        wwpn_int = self._wwpn_pool.alloc()
        wwpn = "AFFEAFFE0000" + "{:04X}".format(wwpn_int)
        return wwpn

Response: Allocates a WWPN unique to this partition in the range of 0xAFFEAFFE00008000 to 0xAFFEAFFE0000FFFF. Returns a string that is a WWPN unique to this partition in the upper case hexadecimal digits in upper case.


Instruction:
Given the following Python 3 function, write the documentation
def wwpn_free(self, wwpn):
        wwpn_int = int(wwpn[-4:], 16)
        self._wwpn_pool.free(wwpn_int)

Response: Free a WWPN allocated with : meth : wwpn_alloc.


Instruction:
Create a Python 3 function to
free a WWPN allocated with wwpn_alloc.

Response:
def wwpn_free_if_allocated(self, wwpn):

        """
        Free a WWPN allocated with :meth:`wwpn_alloc`.

        If the WWPN is not currently allocated or not in the pool
        range, nothing happens.

        Parameters:
          WWPN (string): The WWPN as 16 hexadecimal digits.
        """
        wwpn_int = int(wwpn[-4:], 16)
        self._wwpn_pool.free_if_allocated(wwpn_int)


Instruction:
Can you create a Python 3 function that
adds a faked Port resource.

Response:
def add(self, properties):
        """
        Add a faked Port resource.

        Parameters:

          properties (dict):
            Resource properties.

            Special handling and requirements for certain properties:

            * 'element-id' will be auto-generated with a unique value across
              all instances of this resource type, if not specified.
            * 'element-uri' will be auto-generated based upon the element ID,
              if not specified.
            * 'class' will be auto-generated to 'network-port' or
              'storage-port', if not specified.

            This method also updates the 'network-port-uris' or
            'storage-port-uris' property in the parent Adapter resource, by
            adding the URI for the faked Port resource.

        Returns:
          :class:`zhmcclient_mock.FakedPort`: The faked Port resource.
        """
        new_port = super(FakedPortManager, self).add(properties)
        adapter = self.parent
        if 'network-port-uris' in adapter.properties:
            adapter.properties['network-port-uris'].append(new_port.uri)
        if 'storage-port-uris' in adapter.properties:
            adapter.properties['storage-port-uris'].append(new_port.uri)
        return new_port


Instruction:
Can you write a function in Python 3 where it
removes a faked Port resource from the Adapter resource by its object ID.

Response:
def remove(self, oid):
        """
        Remove a faked Port resource.

        This method also updates the 'network-port-uris' or 'storage-port-uris'
        property in the parent Adapter resource, by removing the URI for the
        faked Port resource.

        Parameters:

          oid (string):
            The object ID of the faked Port resource.
        """
        port = self.lookup_by_oid(oid)
        adapter = self.parent
        if 'network-port-uris' in adapter.properties:
            port_uris = adapter.properties['network-port-uris']
            port_uris.remove(port.uri)
        if 'storage-port-uris' in adapter.properties:
            port_uris = adapter.properties['storage-port-uris']
            port_uris.remove(port.uri)
        super(FakedPortManager, self).remove(oid)


Instruction:
Given the following Python 3 function, write the documentation
def add(self, properties):
        new_vf = super(FakedVirtualFunctionManager, self).add(properties)
        partition = self.parent
        assert 'virtual-function-uris' in partition.properties
        partition.properties['virtual-function-uris'].append(new_vf.uri)
        if 'device-number' not in new_vf.properties:
            devno = partition.devno_alloc()
            new_vf.properties['device-number'] = devno
        return new_vf

Response: Add a faked Virtual Function resource.


Instruction:
Can you write a function in Python 3 where it
removes a faked Virtual Function resource.

Response:
def remove(self, oid):
        """
        Remove a faked Virtual Function resource.

        This method also updates the 'virtual-function-uris' property in the
        parent Partition resource, by removing the URI for the faked Virtual
        Function resource.

        Parameters:

          oid (string):
            The object ID of the faked Virtual Function resource.
        """
        virtual_function = self.lookup_by_oid(oid)
        partition = self.parent
        devno = virtual_function.properties.get('device-number', None)
        if devno:
            partition.devno_free_if_allocated(devno)
        assert 'virtual-function-uris' in partition.properties
        vf_uris = partition.properties['virtual-function-uris']
        vf_uris.remove(virtual_function.uri)
        super(FakedVirtualFunctionManager, self).remove(oid)


Instruction:
Can you tell what is the following Python 3 function doing
def add_metric_group_definition(self, definition):
        assert isinstance(definition, FakedMetricGroupDefinition)
        group_name = definition.name
        if group_name in self._metric_group_defs:
            raise ValueError("A metric group definition with this name "
                             "already exists: {}".format(group_name))
        self._metric_group_defs[group_name] = definition
        self._metric_group_def_names.append(group_name)

Response: Adds a faked metric group definition.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_metric_group_definition(self, group_name):
        if group_name not in self._metric_group_defs:
            raise ValueError("A metric group definition with this name does "
                             "not exist: {}".format(group_name))
        return self._metric_group_defs[group_name]

Response: Get a faked metric group definition by its group name.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def add_metric_values(self, values):
        assert isinstance(values, FakedMetricObjectValues)
        group_name = values.group_name
        if group_name not in self._metric_values:
            self._metric_values[group_name] = []
        self._metric_values[group_name].append(values)
        if group_name not in self._metric_value_names:
            self._metric_value_names.append(group_name)

Response: Adds one set of faked metric values for a particular resource to the internal list of available metric values for a particular metric group.


Instruction:
Explain what the following Python 3 code does
def get_metric_values(self, group_name):
        if group_name not in self._metric_values:
            raise ValueError("Metric values for this group name do not "
                             "exist: {}".format(group_name))
        return self._metric_values[group_name]

Response: Get the faked metric values for a metric group by its metric group_name.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_metric_group_definitions(self):
        group_names = self.properties.get('metric-groups', None)
        if not group_names:
            group_names = self.manager.get_metric_group_definition_names()
        mg_defs = []
        for group_name in group_names:
            try:
                mg_def = self.manager.get_metric_group_definition(group_name)
                mg_defs.append(mg_def)
            except ValueError:
                pass  # ignore metric groups without metric group defs
        return mg_defs

Response: Get the faked metric group definitions for this context.


Instruction:
Create a Python 3 function to
get the metric group infos for this context

Response:
def get_metric_group_infos(self):
        """
        Get the faked metric group definitions for this context object
        that are to be returned from its create operation, in the format
        needed for the "Create Metrics Context" operation response.

        Returns:

          "metric-group-infos" JSON object as described for the "Create Metrics
            Context "operation response.
        """
        mg_defs = self.get_metric_group_definitions()
        mg_infos = []
        for mg_def in mg_defs:
            metric_infos = []
            for metric_name, metric_type in mg_def.types:
                metric_infos.append({
                    'metric-name': metric_name,
                    'metric-type': metric_type,
                })
            mg_info = {
                'group-name': mg_def.name,
                'metric-infos': metric_infos,
            }
            mg_infos.append(mg_info)
        return mg_infos


Instruction:
Can you generate a brief explanation for the following Python 3 code
def get_metric_values(self):
        group_names = self.properties.get('metric-groups', None)
        if not group_names:
            group_names = self.manager.get_metric_values_group_names()
        ret = []
        for group_name in group_names:
            try:
                mo_val = self.manager.get_metric_values(group_name)
                ret_item = (group_name, mo_val)
                ret.append(ret_item)
            except ValueError:
                pass  # ignore metric groups without metric values
        return ret

Response: Get the faked metrics for all metric groups and all resources that have been prepared on this context object.


Instruction:
Explain what the following Python 3 code does
def get_metric_values_response(self):
        mv_list = self.get_metric_values()
        resp_lines = []
        for mv in mv_list:
            group_name = mv[0]
            resp_lines.append('"{}"'.format(group_name))
            mo_vals = mv[1]
            for mo_val in mo_vals:
                resp_lines.append('"{}"'.format(mo_val.resource_uri))
                resp_lines.append(
                    str(timestamp_from_datetime(mo_val.timestamp)))
                v_list = []
                for n, v in mo_val.values:
                    if isinstance(v, six.string_types):
                        v_str = '"{}"'.format(v)
                    else:
                        v_str = str(v)
                    v_list.append(v_str)
                v_line = ','.join(v_list)
                resp_lines.append(v_line)
                resp_lines.append('')
            resp_lines.append('')
        resp_lines.append('')
        return '\n'.join(resp_lines) + '\n'

Response: Get the faked metrics for all metric groups and all resources that have been prepared on the manager object.


Instruction:
Can you tell what is the following Python 3 function doing
def create(self, properties):
        result = self.session.post(self.console.uri + '/user-roles',
                                   body=properties)
        # There should not be overlaps, but just in case there are, the
        # returned props should overwrite the input props:
        props = copy.deepcopy(properties)
        props.update(result)
        name = props.get(self._name_prop, None)
        uri = props[self._uri_prop]
        user_role = UserRole(self, uri, name, props)
        self._name_uri_cache.update(name, uri)
        return user_role

Response: Creates a new User Role in this HMC.


Instruction:
Can you generate the documentation for the following Python 3 function
def add_permission(self, permitted_object, include_members=False,
                       view_only=True):
        """
        Add permission for the specified permitted object(s) to this User Role,
        thereby granting that permission to all users that have this User Role.

        The granted permission depends on the resource class of the permitted
        object(s):

        * For Task resources, the granted permission is task permission for
          that task.

        * For Group resources, the granted permission is object access
          permission for the group resource, and optionally also for the
          group members.

        * For any other resources, the granted permission is object access
          permission for these resources.

        The User Role must be user-defined.

        Authorization requirements:

        * Task permission to the "Manage User Roles" task.

        Parameters:

          permitted_object (:class:`~zhmcclient.BaseResource` or :term:`string`):
            Permitted object(s), either as a Python resource object (e.g.
            :class:`~zhmcclient.Partition`), or as a resource class string (e.g.
            'partition').

            Must not be `None`.

          include_members (bool): Controls whether for Group resources, the
            operation applies additionally to its group member resources.

            This parameter will be ignored when the permitted object does not
            specify Group resources.

          view_only (bool): Controls whether for Task resources, the operation
            aplies to the view-only version of the task (if `True`), or to
            the full version of the task (if `False`). Only certain tasks
            support a view-only version.

            This parameter will be ignored when the permitted object does not
            specify Task resources.

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
        """  # noqa: E501
        if isinstance(permitted_object, BaseResource):
            perm_obj = permitted_object.uri
            perm_type = 'object'
        elif isinstance(permitted_object, six.string_types):
            perm_obj = permitted_object
            perm_type = 'object-class'
        else:
            raise TypeError(
                "permitted_object must be a string or BaseResource, but is: "
                "{}".format(type(permitted_object)))
        body = {
            'permitted-object': perm_obj,
            'permitted-object-type': perm_type,
            'include-members': include_members,
            'view-only-mode': view_only,
        }
        self.manager.session.post(
            self.uri + '/operations/add-permission',
            body=body)

Response: Adds a permission to the User Role.


Instruction:
Can you write a function in Python 3 where it
creates a new storage volume in the HMC and returns a new object with the given properties.

Response:
def create(self, properties, email_to_addresses=None,
               email_cc_addresses=None, email_insert=None):
        """
        Create a :term:`storage volume` in this storage group on the HMC, and
        optionally send emails to storage administrators requesting creation of
        the storage volume on the storage subsystem and setup of any resources
        related to the storage volume (e.g. LUN mask definition on the storage
        subsystem).

        This method performs the "Modify Storage Group Properties" operation,
        requesting creation of the volume.

        Authorization requirements:

        * Object-access permission to this storage group.
        * Task permission to the "Configure Storage - System Programmer" task.

        Parameters:

          properties (dict): Initial property values for the new volume.

            Allowable properties are the fields defined in the
            "storage-volume-request-info" nested object described for
            operation "Modify Storage Group Properties" in the
            :term:`HMC API` book.
            The valid fields are those for the "create" operation. The
            `operation` field must not be provided; it is set automatically
            to the value "create".

            The properties provided in this parameter will be copied and then
            amended with the `operation="create"` field, and then used as a
            single array item for the `storage-volumes` field in the request
            body of the "Modify Storage Group Properties" operation.

            Note that for storage volumes, the HMC does auto-generate a value
            for the "name" property, but that auto-generated name is not unique
            within the parent storage group. If you depend on a unique name,
            you need to specify a "name" property accordingly.

          email_to_addresses (:term:`iterable` of :term:`string`): Email
            addresses of one or more storage administrator to be notified.
            If `None` or empty, no email will be sent.

          email_cc_addresses (:term:`iterable` of :term:`string`): Email
            addresses of one or more storage administrator to be copied
            on the notification email.
            If `None` or empty, nobody will be copied on the email.
            Must be `None` or empty if `email_to_addresses` is `None` or empty.

          email_insert (:term:`string`): Additional text to be inserted in the
            notification email.
            The text can include HTML formatting tags.
            If `None`, no additional text will be inserted.
            Must be `None` or empty if `email_to_addresses` is `None` or empty.

        Returns:

          StorageVolume:
            The resource object for the new storage volume.
            The object will have the following properties set:

            - 'element-uri' as returned by the HMC
            - 'element-id' as determined from the 'element-uri' property
            - 'class' and 'parent'
            - additional properties as specified in the input properties

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`

        Example::

            stovol1 = fcp_stogrp.storage_volumes.create(
                properties=dict(
                    name='vol1',
                    size=30,  # GiB
            ))
        """

        volreq_obj = copy.deepcopy(properties)
        volreq_obj['operation'] = 'create'
        body = {
            'storage-volumes': [volreq_obj],
        }
        if email_to_addresses:
            body['email-to-addresses'] = email_to_addresses
            if email_cc_addresses:
                body['email-cc-addresses'] = email_cc_addresses
            if email_insert:
                body['email-insert'] = email_insert
        else:
            if email_cc_addresses:
                raise ValueError("email_cc_addresses must not be specified if "
                                 "there is no email_to_addresses: %r" %
                                 email_cc_addresses)
            if email_insert:
                raise ValueError("email_insert must not be specified if "
                                 "there is no email_to_addresses: %r" %
                                 email_insert)

        result = self.session.post(
            self.storage_group.uri + '/operations/modify',
            body=body)
        uri = result['element-uris'][0]

        storage_volume = self.resource_object(uri, properties)

        # The name is not guaranteed to be unique, so we don't maintain
        # a name-to-uri cache for storage volumes.

        return storage_volume


Instruction:
Can you generate a brief explanation for the following Python 3 code
def oid(self):
        m = re.match(r'^/api/storage-groups/[^/]*/storage-volumes/([^/]*)$',
                     self.uri)
        oid = m.group(1)
        return oid

Response: Return the object ID of this storage volume.


Instruction:
Can you tell what is the following Python 3 function doing
def delete(self, email_to_addresses=None, email_cc_addresses=None,
               email_insert=None):
        """
        Delete this storage volume on the HMC, and optionally send emails to
        storage administrators requesting deletion of the storage volume on the
        storage subsystem and cleanup of any resources related to the storage
        volume (e.g. LUN mask definitions on a storage subsystem).

        This method performs the "Modify Storage Group Properties" operation,
        requesting deletion of the volume.

        Authorization requirements:

        * Object-access permission to the storage group owning this storage
          volume.
        * Task permission to the "Configure Storage - System Programmer" task.

        Parameters:

          email_to_addresses (:term:`iterable` of :term:`string`): Email
            addresses of one or more storage administrator to be notified.
            If `None` or empty, no email will be sent.

          email_cc_addresses (:term:`iterable` of :term:`string`): Email
            addresses of one or more storage administrator to be copied
            on the notification email.
            If `None` or empty, nobody will be copied on the email.
            Must be `None` or empty if `email_to_addresses` is `None` or empty.

          email_insert (:term:`string`): Additional text to be inserted in the
            notification email.
            The text can include HTML formatting tags.
            If `None`, no additional text will be inserted.
            Must be `None` or empty if `email_to_addresses` is `None` or empty.

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
        """

        volreq_obj = {
            'operation': 'delete',
            'element-uri': self.uri,
        }
        body = {
            'storage-volumes': [
                volreq_obj
            ],
        }
        if email_to_addresses:
            body['email-to-addresses'] = email_to_addresses
            if email_cc_addresses:
                body['email-cc-addresses'] = email_cc_addresses
            if email_insert:
                body['email-insert'] = email_insert
        else:
            if email_cc_addresses:
                raise ValueError("email_cc_addresses must not be specified if "
                                 "there is no email_to_addresses: %r" %
                                 email_cc_addresses)
            if email_insert:
                raise ValueError("email_insert must not be specified if "
                                 "there is no email_to_addresses: %r" %
                                 email_insert)

        self.manager.session.post(
            self.manager.storage_group.uri + '/operations/modify',
            body=body)

        self.manager._name_uri_cache.delete(
            self.properties.get(self.manager._name_prop, None))

Response: Delete this storage volume on the HMC and optionally send emails to the storage administrators and cleanup of any resources related to the storage volume.


Instruction:
Can you generate the documentation for the following Python 3 function
def update_properties(self, properties, email_to_addresses=None,
                          email_cc_addresses=None, email_insert=None):
        """
        Update writeable properties of this storage volume on the HMC, and
        optionally send emails to storage administrators requesting
        modification of the storage volume on the storage subsystem and of any
        resources related to the storage volume.

        This method performs the "Modify Storage Group Properties" operation,
        requesting modification of the volume.

        Authorization requirements:

        * Object-access permission to the storage group owning this storage
          volume.
        * Task permission to the "Configure Storage - System Programmer" task.

        Parameters:

          properties (dict): New property values for the volume.
            Allowable properties are the fields defined in the
            "storage-volume-request-info" nested object for the "modify"
            operation. That nested object is described in section "Request body
            contents" for operation "Modify Storage Group Properties" in the
            :term:`HMC API` book.

            The properties provided in this parameter will be copied and then
            amended with the `operation="modify"` and `element-uri` properties,
            and then used as a single array item for the `storage-volumes`
            field in the request body of the "Modify Storage Group Properties"
            operation.

          email_to_addresses (:term:`iterable` of :term:`string`): Email
            addresses of one or more storage administrator to be notified.
            If `None` or empty, no email will be sent.

          email_cc_addresses (:term:`iterable` of :term:`string`): Email
            addresses of one or more storage administrator to be copied
            on the notification email.
            If `None` or empty, nobody will be copied on the email.
            Must be `None` or empty if `email_to_addresses` is `None` or empty.

          email_insert (:term:`string`): Additional text to be inserted in the
            notification email.
            The text can include HTML formatting tags.
            If `None`, no additional text will be inserted.
            Must be `None` or empty if `email_to_addresses` is `None` or empty.

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
        """

        volreq_obj = copy.deepcopy(properties)
        volreq_obj['operation'] = 'modify'
        volreq_obj['element-uri'] = self.uri
        body = {
            'storage-volumes': [volreq_obj],
        }
        if email_to_addresses:
            body['email-to-addresses'] = email_to_addresses
            if email_cc_addresses:
                body['email-cc-addresses'] = email_cc_addresses
            if email_insert:
                body['email-insert'] = email_insert
        else:
            if email_cc_addresses:
                raise ValueError("email_cc_addresses must not be specified if "
                                 "there is no email_to_addresses: %r" %
                                 email_cc_addresses)
            if email_insert:
                raise ValueError("email_insert must not be specified if "
                                 "there is no email_to_addresses: %r" %
                                 email_insert)

        self.manager.session.post(
            self.manager.storage_group.uri + '/operations/modify',
            body=body)

        self.properties.update(copy.deepcopy(properties))

Response: This method is used to update writeable properties of the storage group with the provided properties.


Instruction:
Can you generate the documentation for the following Python 3 function
def indicate_fulfillment_fcp(self, wwpn, lun, host_port):

        # The operation requires exactly 16 characters in lower case
        wwpn_16 = format(int(wwpn, 16), '016x')
        lun_16 = format(int(lun, 16), '016x')

        body = {
            'world-wide-port-name': wwpn_16,
            'logical-unit-number': lun_16,
            'adapter-port-uri': host_port.uri,
        }
        self.manager.session.post(
            self.uri + '/operations/fulfill-fcp-storage-volume',
            body=body)

Response: This method is used to indicate the completion of a FCP storage volume. This method is used to indicate the actual FCP storage volume and the actual FCP storage volume on the storage subsystem.


Instruction:
Implement a Python 3 function for
returning the exception as a string in a Python definition - style format.

Response:
def str_def(self):
        """
        :term:`string`: The exception as a string in a Python definition-style
        format, e.g. for parsing by scripts:

        .. code-block:: text

            classname={}; read_timeout={}; read_retries={}; message={};
        """
        return "classname={!r}; read_timeout={!r}; read_retries={!r}; " \
            "message={!r};". \
            format(self.__class__.__name__, self.read_timeout,
                   self.read_retries, self.args[0])


Instruction:
How would you implement a function in Python 3 that
returns the exception as a string in a Python definition - style format.

Response:
def str_def(self):
        """
        :term:`string`: The exception as a string in a Python definition-style
        format, e.g. for parsing by scripts:

        .. code-block:: text

            classname={}; connect_retries={}; message={};
        """
        return "classname={!r}; connect_retries={!r}; message={!r};". \
            format(self.__class__.__name__, self.connect_retries, self.args[0])


Instruction:
Explain what the following Python 3 code does
def str_def(self):
        return "classname={!r}; line={!r}; column={!r}; message={!r};". \
            format(self.__class__.__name__, self.line, self.column,
                   self.args[0])

Response:
The exception as a string in a Python definition - style
Taxonomy format e. g. for parsing by scripts.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def str_def(self):
        return "classname={!r}; min_api_version={!r}; api_version={!r}; " \
            "message={!r};". \
            format(self.__class__.__name__, self.min_api_version,
                   self.api_version, self.args[0])

Response:
Return the exception as a string in a Python definition - style
            format.


Instruction:
Make a summary of the following Python 3 code
def str_def(self):
        return "classname={!r}; operation_timeout={!r}; message={!r};". \
            format(self.__class__.__name__, self.operation_timeout,
                   self.args[0])

Response:
Return the exception as a string in a Python definition - style
            format.


Instruction:
Can you generate the documentation for the following Python 3 function
def reassign_port(self, port):
        body = {'adapter-port-uri': port.uri}
        self.manager.session.post(
            self._uri + '/operations/reassign-storage-adapter-port',
            body=body)
        self.properties.update(body)

Response: Reassign this HBA to a new underlying : term:`FCP port.


Instruction:
Here you have a function in Python 3, explain what it does
def list(self, full_properties=False, filter_args=None):
        resource_obj_list = []
        uris = self.partition.get_property('virtual-function-uris')
        if uris:
            for uri in uris:

                resource_obj = self.resource_class(
                    manager=self,
                    uri=uri,
                    name=None,
                    properties=None)

                if self._matches_filters(resource_obj, filter_args):
                    resource_obj_list.append(resource_obj)
                    if full_properties:
                        resource_obj.pull_full_properties()

        self._name_uri_cache.update_from(resource_obj_list)
        return resource_obj_list

Response: Returns a list of Virtual Functions of this Partition.


Instruction:
How would you explain what the following Python 3 function does
def get_connected_nics(self):
        result = self.manager.session.get(
            self.uri + '/operations/get-connected-vnics')
        nic_uris = result['connected-vnic-uris']
        nic_list = []
        parts = {}  # Key: Partition ID; Value: Partition object
        for nic_uri in nic_uris:
            m = re.match(r"^/api/partitions/([^/]+)/nics/([^/]+)/?$", nic_uri)
            part_id = m.group(1)
            nic_id = m.group(2)
            # We remember created Partition objects and reuse them.
            try:
                part = parts[part_id]
            except KeyError:
                part = self.manager.cpc.partitions.resource_object(part_id)
                parts[part_id] = part
            nic = part.nics.resource_object(nic_id)
            nic_list.append(nic)
        return nic_list

Response: Returns a list of NICS connected to this Virtual Switch.


Instruction:
Can you write a function in Python 3 where it
returns a list of all ports of this Adapter.

Response:
def list(self, full_properties=False, filter_args=None):
        """
        List the Ports of this Adapter.

        If the adapter does not have any ports, an empty list is returned.

        Authorization requirements:

        * Object-access permission to this Adapter.

        Parameters:

          full_properties (bool):
            Controls whether the full set of resource properties should be
            retrieved, vs. only the short set as returned by the list
            operation.

          filter_args (dict):
            Filter arguments that narrow the list of returned resources to
            those that match the specified filter arguments. For details, see
            :ref:`Filtering`.

            `None` causes no filtering to happen, i.e. all resources are
            returned.

        Returns:

          : A list of :class:`~zhmcclient.Port` objects.

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
        """
        uris_prop = self.adapter.port_uris_prop
        if not uris_prop:
            # Adapter does not have any ports
            return []

        uris = self.adapter.get_property(uris_prop)
        assert uris is not None

        # TODO: Remove the following circumvention once fixed.
        # The following line circumvents a bug for FCP adapters that sometimes
        # causes duplicate URIs to show up in this property:
        uris = list(set(uris))

        resource_obj_list = []
        for uri in uris:

            resource_obj = self.resource_class(
                manager=self,
                uri=uri,
                name=None,
                properties=None)

            if self._matches_filters(resource_obj, filter_args):
                resource_obj_list.append(resource_obj)
                if full_properties:
                    resource_obj.pull_full_properties()

        self._name_uri_cache.update_from(resource_obj_list)
        return resource_obj_list


Instruction:
Can you implement a function in Python 3 that
adds the specified User Role to this User.

Response:
def add_user_role(self, user_role):
        """
        Add the specified User Role to this User.

        This User must not be a system-defined or pattern-based user.

        Authorization requirements:

        * Task permission to the "Manage Users" task to modify a standard user
          or the "Manage User Templates" task to modify a template user.

        Parameters:

          user_role (:class:`~zhmcclient.UserRole`): User Role to be added.
            Must not be `None`.

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
        """
        body = {
            'user-role-uri': user_role.uri
        }
        self.manager.session.post(
            self.uri + '/operations/add-user-role',
            body=body)


Instruction:
Can you generate a brief explanation for the following Python 3 code
def remove_user_role(self, user_role):
        body = {
            'user-role-uri': user_role.uri
        }
        self.manager.session.post(
            self.uri + '/operations/remove-user-role',
            body=body)

Response: Removes the specified User Role from this User.


Instruction:
Explain what the following Python 3 code does
def get(self, uri, logon_required=True):
        try:
            return self._urihandler.get(self._hmc, uri, logon_required)
        except HTTPError as exc:
            raise zhmcclient.HTTPError(exc.response())
        except ConnectionError as exc:
            raise zhmcclient.ConnectionError(exc.message, None)

Response: Perform a HTTP GET method against the resource identified by a URI.


Instruction:
Implement a function in Python 3 to
perform an HTTP POST operation against the resource identified by a URI.

Response:
def post(self, uri, body=None, logon_required=True,
             wait_for_completion=True, operation_timeout=None):
        """
        Perform the HTTP POST method against the resource identified by a URI,
        using a provided request body, on the faked HMC.

        HMC operations using HTTP POST are either synchronous or asynchronous.
        Asynchronous operations return the URI of an asynchronously executing
        job that can be queried for status and result.

        Examples for synchronous operations:

        * With no response body: "Logon", "Update CPC Properties"
        * With a response body: "Create Partition"

        Examples for asynchronous operations:

        * With no ``job-results`` field in the completed job status response:
          "Start Partition"
        * With a ``job-results`` field in the completed job status response
          (under certain conditions): "Activate a Blade", or "Set CPC Power
          Save"

        The `wait_for_completion` parameter of this method can be used to deal
        with asynchronous HMC operations in a synchronous way.

        Parameters:

          uri (:term:`string`):
            Relative URI path of the resource, e.g. "/api/session".
            This URI is relative to the base URL of the session (see the
            :attr:`~zhmcclient.Session.base_url` property).
            Must not be `None`.

          body (:term:`json object`):
            JSON object to be used as the HTTP request body (payload).
            `None` means the same as an empty dictionary, namely that no HTTP
            body is included in the request.

          logon_required (bool):
            Boolean indicating whether the operation requires that the session
            is logged on to the HMC. For example, the "Logon" operation does
            not require that.

            Because this is a faked HMC, this does not perform a real logon,
            but it is still used to update the state in the faked HMC.

          wait_for_completion (bool):
            Boolean controlling whether this method should wait for completion
            of the requested HMC operation, as follows:

            * If `True`, this method will wait for completion of the requested
              operation, regardless of whether the operation is synchronous or
              asynchronous.

              This will cause an additional entry in the time statistics to be
              created for the asynchronous operation and waiting for its
              completion. This entry will have a URI that is the targeted URI,
              appended with "+completion".

            * If `False`, this method will immediately return the result of the
              HTTP POST method, regardless of whether the operation is
              synchronous or asynchronous.

          operation_timeout (:term:`number`):
            Timeout in seconds, when waiting for completion of an asynchronous
            operation. The special value 0 means that no timeout is set. `None`
            means that the default async operation timeout of the session is
            used.

            For `wait_for_completion=True`, a
            :exc:`~zhmcclient.OperationTimeout` is raised when the timeout
            expires.

            For `wait_for_completion=False`, this parameter has no effect.

        Returns:

          :term:`json object`:

            If `wait_for_completion` is `True`, returns a JSON object
            representing the response body of the synchronous operation, or the
            response body of the completed job that performed the asynchronous
            operation. If a synchronous operation has no response body, `None`
            is returned.

            If `wait_for_completion` is `False`, returns a JSON object
            representing the response body of the synchronous or asynchronous
            operation. In case of an asynchronous operation, the JSON object
            will have a member named ``job-uri``, whose value can be used with
            the :meth:`~zhmcclient.Session.query_job_status` method to
            determine the status of the job and the result of the original
            operation, once the job has completed.

            See the section in the :term:`HMC API` book about the specific HMC
            operation and about the 'Query Job Status' operation, for a
            description of the members of the returned JSON objects.

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError` (not implemented)
          :exc:`~zhmcclient.AuthError` (not implemented)
          :exc:`~zhmcclient.ConnectionError`
        """
        try:
            return self._urihandler.post(self._hmc, uri, body, logon_required,
                                         wait_for_completion)
        except HTTPError as exc:
            raise zhmcclient.HTTPError(exc.response())
        except ConnectionError as exc:
            raise zhmcclient.ConnectionError(exc.message, None)


Instruction:
Can you tell what is the following Python 3 function doing
def notifications(self):

        while True:
            with self._handover_cond:

                # Wait until MessageListener has a new notification
                while len(self._handover_dict) == 0:
                    self._handover_cond.wait(self._wait_timeout)

                if self._handover_dict['headers'] is None:
                    return

                # Process the notification
                yield (self._handover_dict['headers'],
                       self._handover_dict['message'])

                # Indicate to MessageListener that we are ready for next
                # notification
                del self._handover_dict['headers']
                del self._handover_dict['message']
                self._handover_cond.notifyAll()

Response: A method that yields all JMS messages received by this notification receiver.


Instruction:
Can you create a Python 3 function that
returns a list of console objects that are connected to this HMC.

Response:
def list(self, full_properties=True, filter_args=None):
        """
        List the (one) :term:`Console` representing the HMC this client is
        connected to.

        Authorization requirements:

        * None

        Parameters:

          full_properties (bool):
            Controls whether the full set of resource properties should be
            retrieved, vs. only a short set consisting of 'object-uri'.

          filter_args (dict):
            This parameter exists for consistency with other list() methods
            and will be ignored.

        Returns:

          : A list of :class:`~zhmcclient.Console` objects, containing the one
          :term:`Console` representing the HMC this client is connected to.

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
        """
        uri = self._base_uri  # There is only one console object.
        if full_properties:
            props = self.session.get(uri)
        else:
            # Note: The Console resource's Object ID is not part of its URI.
            props = {
                self._uri_prop: uri,
            }
        resource_obj = self.resource_class(
            manager=self,
            uri=props[self._uri_prop],
            name=props.get(self._name_prop, None),
            properties=props)
        return [resource_obj]


Instruction:
Write a Python 3 function for
returning a manager object for the Storage Groups in scope of this Console.

Response:
def storage_groups(self):
        """
        :class:`~zhmcclient.StorageGroupManager`:
          Manager object for the Storage Groups in scope of this Console.
        """
        # We do here some lazy loading.
        if not self._storage_groups:
            self._storage_groups = StorageGroupManager(self)
        return self._storage_groups


Instruction:
Create a Python 3 function for
accessing to the users in this Console.

Response:
def users(self):
        """
        :class:`~zhmcclient.UserManager`: Access to the :term:`Users <User>` in
        this Console.
        """
        # We do here some lazy loading.
        if not self._users:
            self._users = UserManager(self)
        return self._users


Instruction:
Can you write a function in Python 3 where it
accesses to the User Roles in this Console.

Response:
def user_roles(self):
        """
        :class:`~zhmcclient.UserRoleManager`: Access to the
        :term:`User Roles <User Role>` in this Console.
        """
        # We do here some lazy loading.
        if not self._user_roles:
            self._user_roles = UserRoleManager(self)
        return self._user_roles


Instruction:
Make a summary of the following Python 3 code
def user_patterns(self):
        # We do here some lazy loading.
        if not self._user_patterns:
            self._user_patterns = UserPatternManager(self)
        return self._user_patterns

Response: Access to the User Patterns class.


Instruction:
Can you tell what is the following Python 3 function doing
def password_rules(self):
        # We do here some lazy loading.
        if not self._password_rules:
            self._password_rules = PasswordRuleManager(self)
        return self._password_rules

Response: Access to the password rules of the current Console.


Instruction:
Can you generate a brief explanation for the following Python 3 code
def tasks(self):
        # We do here some lazy loading.
        if not self._tasks:
            self._tasks = TaskManager(self)
        return self._tasks

Response: Access to the tasks in this Console.


Instruction:
Create a Python 3 function for
accessing to the LDAP Server Definitions in this Console.

Response:
def ldap_server_definitions(self):
        """
        :class:`~zhmcclient.LdapServerDefinitionManager`: Access to the
        :term:`LDAP Server Definitions <LDAP Server Definition>` in this
        Console.
        """
        # We do here some lazy loading.
        if not self._ldap_server_definitions:
            self._ldap_server_definitions = LdapServerDefinitionManager(self)
        return self._ldap_server_definitions


Instruction:
How would you explain what the following Python 3 function does
def unmanaged_cpcs(self):
        # We do here some lazy loading.
        if not self._unmanaged_cpcs:
            self._unmanaged_cpcs = UnmanagedCpcManager(self)
        return self._unmanaged_cpcs

Response: Access to the UnmanagedCpcManager object.


Instruction:
Can you write a function in Python 3 where it
restarts the HMC with the specified parameters.

Response:
def restart(self, force=False, wait_for_available=True,
                operation_timeout=None):
        """
        Restart the HMC represented by this Console object.

        Once the HMC is online again, this Console object, as well as any other
        resource objects accessed through this HMC, can continue to be used.
        An automatic re-logon will be performed under the covers, because the
        HMC restart invalidates the currently used HMC session.

        Authorization requirements:

        * Task permission for the "Shutdown/Restart" task.
        * "Remote Restart" must be enabled on the HMC.

        Parameters:

          force (bool):
            Boolean controlling whether the restart operation is processed when
            users are connected (`True`) or not (`False`). Users in this sense
            are local or remote GUI users. HMC WS API clients do not count as
            users for this purpose.

          wait_for_available (bool):
            Boolean controlling whether this method should wait for the HMC to
            become available again after the restart, as follows:

            * If `True`, this method will wait until the HMC has restarted and
              is available again. The
              :meth:`~zhmcclient.Client.query_api_version` method will be used
              to check for availability of the HMC.

            * If `False`, this method will return immediately once the HMC
              has accepted the request to be restarted.

          operation_timeout (:term:`number`):
            Timeout in seconds, for waiting for HMC availability after the
            restart. The special value 0 means that no timeout is set. `None`
            means that the default async operation timeout of the session is
            used. If the timeout expires when `wait_for_available=True`, a
            :exc:`~zhmcclient.OperationTimeout` is raised.

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
          :exc:`~zhmcclient.OperationTimeout`: The timeout expired while
            waiting for the HMC to become available again after the restart.
        """
        body = {'force': force}
        self.manager.session.post(self.uri + '/operations/restart', body=body)
        if wait_for_available:
            time.sleep(10)
            self.manager.client.wait_for_available(
                operation_timeout=operation_timeout)


Instruction:
Create a Python 3 function for
shutting down and power off the HMC.

Response:
def shutdown(self, force=False):
        """
        Shut down and power off the HMC represented by this Console object.

        While the HMC is powered off, any Python resource objects retrieved
        from this HMC may raise exceptions upon further use.

        In order to continue using Python resource objects retrieved from this
        HMC, the HMC needs to be started again (e.g. by powering it on
        locally). Once the HMC is available again, Python resource objects
        retrieved from that HMC can continue to be used.
        An automatic re-logon will be performed under the covers, because the
        HMC startup invalidates the currently used HMC session.

        Authorization requirements:

        * Task permission for the "Shutdown/Restart" task.
        * "Remote Shutdown" must be enabled on the HMC.

        Parameters:

          force (bool):
            Boolean controlling whether the shutdown operation is processed
            when users are connected (`True`) or not (`False`). Users in this
            sense are local or remote GUI users. HMC WS API clients do not
            count as users for this purpose.

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
        """
        body = {'force': force}
        self.manager.session.post(self.uri + '/operations/shutdown', body=body)


Instruction:
Given the following Python 3 function, write the documentation
def _time_query_parms(begin_time, end_time):
        query_parms = []
        if begin_time is not None:
            begin_ts = timestamp_from_datetime(begin_time)
            qp = 'begin-time={}'.format(begin_ts)
            query_parms.append(qp)
        if end_time is not None:
            end_ts = timestamp_from_datetime(end_time)
            qp = 'end-time={}'.format(end_ts)
            query_parms.append(qp)
        query_parms_str = '&'.join(query_parms)
        if query_parms_str:
            query_parms_str = '?' + query_parms_str
        return query_parms_str

Response: Return the URI query paramterer string for the specified begin time and end time.


Instruction:
Implement a Python 3 function for
getting the console audit log entries optionally filtered by their respective begin_time and end_time.

Response:
def get_audit_log(self, begin_time=None, end_time=None):
        """
        Return the console audit log entries, optionally filtered by their
        creation time.

        Authorization requirements:

        * Task permission to the "Audit and Log Management" task.

        Parameters:

          begin_time (:class:`~py:datetime.datetime`):
            Begin time for filtering. Log entries with a creation time older
            than the begin time will be omitted from the results.

            If `None`, no such filtering is performed (and the oldest available
            log entries will be included).

          end_time (:class:`~py:datetime.datetime`):
            End time for filtering. Log entries with a creation time newer
            than the end time will be omitted from the results.

            If `None`, no such filtering is performed (and the newest available
            log entries will be included).

        Returns:

          :term:`json object`:
            A JSON object with the log entries, as described in section
            'Response body contents' of operation 'Get Console Audit Log' in
            the :term:`HMC API` book.

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
        """
        query_parms = self._time_query_parms(begin_time, end_time)
        uri = self.uri + '/operations/get-audit-log' + query_parms
        result = self.manager.session.post(uri)
        return result


Instruction:
Can you create a Python 3 function that
returns a list of unmanaged CPCs of this HMC.

Response:
def list_unmanaged_cpcs(self, name=None):
        """
        List the unmanaged CPCs of this HMC.

        For details, see :meth:`~zhmcclient.UnmanagedCpc.list`.

        Authorization requirements:

        * None

        Parameters:

          name (:term:`string`):
            Regular expression pattern for the CPC name, as a filter that
            narrows the list of returned CPCs to those whose name property
            matches the specified pattern.

            `None` causes no filtering to happen, i.e. all unmanaged CPCs
            discovered by the HMC are returned.

        Returns:

          : A list of :class:`~zhmcclient.UnmanagedCpc` objects.

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
        """
        filter_args = dict()
        if name is not None:
            filter_args['name'] = name
        cpcs = self.unmanaged_cpcs.list(filter_args=filter_args)
        return cpcs


Instruction:
Can you generate the documentation for the following Python 3 function
def lpars(self):
        # We do here some lazy loading.
        if not self._lpars:
            self._lpars = LparManager(self)
        return self._lpars

Response: Access to the LPARs of this CPC.


Instruction:
Can you implement a function in Python 3 that
accesses to the PartitionManager instance for this CPC.

Response:
def partitions(self):
        """
        :class:`~zhmcclient.PartitionManager`: Access to the
        :term:`Partitions <Partition>` in this CPC.
        """
        # We do here some lazy loading.
        if not self._partitions:
            self._partitions = PartitionManager(self)
        return self._partitions


Instruction:
How would you explain what the following Python 3 function does
def adapters(self):
        # We do here some lazy loading.
        if not self._adapters:
            self._adapters = AdapterManager(self)
        return self._adapters

Response: Access to the adapters in this CPC.


Instruction:
How would you explain what the following Python 3 function does
def virtual_switches(self):
        # We do here some lazy loading.
        if not self._virtual_switches:
            self._virtual_switches = VirtualSwitchManager(self)
        return self._virtual_switches

Response: Access to the Virtual Switches object in this CPC.


Instruction:
Can you tell what is the following Python 3 function doing
def reset_activation_profiles(self):
        # We do here some lazy loading.
        if not self._reset_activation_profiles:
            self._reset_activation_profiles = \
                ActivationProfileManager(self, profile_type='reset')
        return self._reset_activation_profiles

Response: Access to the ActivationProfileManager


Instruction:
Implement a function in Python 3 to
access to the ActivationProfileManager for this CPC.

Response:
def image_activation_profiles(self):
        """
        :class:`~zhmcclient.ActivationProfileManager`: Access to the
        :term:`Image Activation Profiles <Image Activation Profile>` in this
        CPC.
        """
        # We do here some lazy loading.
        if not self._image_activation_profiles:
            self._image_activation_profiles = \
                ActivationProfileManager(self, profile_type='image')
        return self._image_activation_profiles


Instruction:
Explain what the following Python 3 code does
def load_activation_profiles(self):
        # We do here some lazy loading.
        if not self._load_activation_profiles:
            self._load_activation_profiles = \
                ActivationProfileManager(self, profile_type='load')
        return self._load_activation_profiles

Response: Access to the ActivationProfileManager


Instruction:
Can you create a Python 3 function that
returns the maximum number of active logical partitions or partitions of this CPC.

Response:
def maximum_active_partitions(self):
        """
        Integer: The maximum number of active logical partitions or partitions
        of this CPC.

        The following table shows the maximum number of active logical
        partitions or partitions by machine generations supported at the HMC
        API:

        =========================  ==================
        Machine generation         Maximum partitions
        =========================  ==================
        z196                                      60
        z114                                      30
        zEC12                                     60
        zBC12                                     30
        z13 / Emperor                             85
        z13s / Rockhopper                         40
        z14 / Emperor II                          85
        z14-ZR1 / Rockhopper II                   40
        =========================  ==================

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
          :exc:`ValueError`: Unknown machine type
        """
        machine_type = self.get_property('machine-type')
        try:
            max_parts = self._MAX_PARTITIONS_BY_MACHINE_TYPE[machine_type]
        except KeyError:
            raise ValueError("Unknown machine type: {!r}".format(machine_type))
        return max_parts


Instruction:
Can you generate a brief explanation for the following Python 3 code
def feature_info(self):
        feature_list = self.prop('available-features-list', None)
        if feature_list is None:
            raise ValueError("Firmware features are not supported on CPC %s" %
                             self.name)
        return feature_list

Response: Returns a list of information about the features available for this CPC.


Instruction:
Implement a Python 3 function for
starting this HMC and return a new instance of a new HMC.

Response:
def start(self, wait_for_completion=True, operation_timeout=None):
        """
        Start this CPC, using the HMC operation "Start CPC".

        Authorization requirements:

        * Object-access permission to this CPC.
        * Task permission for the "Start (start a single DPM system)" task.

        Parameters:

          wait_for_completion (bool):
            Boolean controlling whether this method should wait for completion
            of the requested asynchronous HMC operation, as follows:

            * If `True`, this method will wait for completion of the
              asynchronous job performing the operation.

            * If `False`, this method will return immediately once the HMC has
              accepted the request to perform the operation.

          operation_timeout (:term:`number`):
            Timeout in seconds, for waiting for completion of the asynchronous
            job performing the operation. The special value 0 means that no
            timeout is set. `None` means that the default async operation
            timeout of the session is used. If the timeout expires when
            `wait_for_completion=True`, a
            :exc:`~zhmcclient.OperationTimeout` is raised.

        Returns:

          `None` or :class:`~zhmcclient.Job`:

            If `wait_for_completion` is `True`, returns `None`.

            If `wait_for_completion` is `False`, returns a
            :class:`~zhmcclient.Job` object representing the asynchronously
            executing job on the HMC.

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
          :exc:`~zhmcclient.OperationTimeout`: The timeout expired while
            waiting for completion of the operation.
        """
        result = self.manager.session.post(
            self.uri + '/operations/start',
            wait_for_completion=wait_for_completion,
            operation_timeout=operation_timeout)
        return result


Instruction:
Create a Python 3 function for
importing activation profiles and/or system activity profiles for this CPC from the SE hard drive into the CPC using the HMC operation "Import Profiles". This operation is not permitted when the CPC is in DPM mode. Authorization requirements: * Object-access permission to this CPC. * Task permission for the "CIM Actions ExportSettingsData" task. Parameters: profile_area (int): The numbered hard drive area (1-4) from which the profiles are imported. wait_for_completion (bool): Boolean controlling whether this method should wait for completion of the requested asynchronous HMC operation, as follows: * If `True`, this method will wait for completion of the asynchronous job performing the operation. * If `False`, this method will return immediately once the HMC has accepted the request to perform the operation. operation_timeout (:term:`number`): Timeout in seconds, for waiting for completion of the asynchronous job performing the operation. The special value 0 means that no timeout is set. `None` means that the default async operation timeout of the session is used. If the timeout expires when `wait_for_completion=True`, a :exc:`~zhmcclient.OperationTimeout` is raised. Returns: `None` or :class:`~zhmcclient.Job`: If `wait_for_completion` is `True`, returns `None`. If `wait_for_completion` is `False`, returns a :class:`~zhmcclient.Job` object representing the asynchronously executing job on the HMC. Raises: :exc:`~zhmcclient.HTTPError` :exc:`~zhmcclient.ParseError` :exc:`~zhmcclient.AuthError` :exc:`~zhmcclient.ConnectionError` :exc:`~zhmcclient.OperationTimeout`: The timeout expired while waiting for completion of the operation.

Response:
def import_profiles(self, profile_area, wait_for_completion=True,
                        operation_timeout=None):
        """
        Import activation profiles and/or system activity profiles for this CPC
        from the SE hard drive into the CPC using the HMC operation
        "Import Profiles".

        This operation is not permitted when the CPC is in DPM mode.

        Authorization requirements:

        * Object-access permission to this CPC.
        * Task permission for the "CIM Actions ExportSettingsData" task.

        Parameters:

          profile_area (int):
            The numbered hard drive area (1-4) from which the profiles are
            imported.

          wait_for_completion (bool):
            Boolean controlling whether this method should wait for completion
            of the requested asynchronous HMC operation, as follows:

            * If `True`, this method will wait for completion of the
              asynchronous job performing the operation.

            * If `False`, this method will return immediately once the HMC has
              accepted the request to perform the operation.

          operation_timeout (:term:`number`):
            Timeout in seconds, for waiting for completion of the asynchronous
            job performing the operation. The special value 0 means that no
            timeout is set. `None` means that the default async operation
            timeout of the session is used. If the timeout expires when
            `wait_for_completion=True`, a
            :exc:`~zhmcclient.OperationTimeout` is raised.

        Returns:

          `None` or :class:`~zhmcclient.Job`:

            If `wait_for_completion` is `True`, returns `None`.

            If `wait_for_completion` is `False`, returns a
            :class:`~zhmcclient.Job` object representing the asynchronously
            executing job on the HMC.

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
          :exc:`~zhmcclient.OperationTimeout`: The timeout expired while
            waiting for completion of the operation.
        """
        body = {'profile-area': profile_area}
        result = self.manager.session.post(
            self.uri + '/operations/import-profiles',
            body,
            wait_for_completion=wait_for_completion,
            operation_timeout=operation_timeout)
        return result


Instruction:
Can you generate the documentation for the following Python 3 function
def get_wwpns(self, partitions):
        body = {'partitions': [p.uri for p in partitions]}
        result = self.manager.session.post(self._uri + '/operations/'
                                           'export-port-names-list', body=body)
        # Parse the returned comma-separated string for each WWPN into a dict:
        wwpn_list = []
        dict_keys = ('partition-name', 'adapter-id', 'device-number', 'wwpn')
        for wwpn_item in result['wwpn-list']:
            dict_values = wwpn_item.split(',')
            wwpn_list.append(dict(zip(dict_keys, dict_values)))
        return wwpn_list

Response: This method returns the WWPNs of the host ports of the HBA of the FCP Adapter.


Instruction:
How would you implement a function in Python 3 that
returns a list of free crypto domains for the specified crypto adapter and cell.

Response:
def get_free_crypto_domains(self, crypto_adapters=None):
        """
        Return a list of crypto domains that are free for usage on a list of
        crypto adapters in this CPC.

        A crypto domain is considered free for usage if it is not assigned to
        any defined partition of this CPC in access mode 'control-usage' on any
        of the specified crypto adapters.

        For this test, all currently defined partitions of this CPC are
        checked, regardless of whether or not they are active. This ensures
        that a crypto domain that is found to be free for usage can be assigned
        to a partition for 'control-usage' access to the specified crypto
        adapters, without causing a crypto domain conflict when activating that
        partition.

        Note that a similar notion of free domains does not exist for access
        mode 'control', because a crypto domain on a crypto adapter can be
        in control access by multiple active partitions.

        This method requires the CPC to be in DPM mode.

        **Example:**

            .. code-block:: text

                           crypto domains
               adapters     0   1   2   3
                          +---+---+---+---+
                 c1       |A,c|a,c|   | C |
                          +---+---+---+---+
                 c2       |b,c|B,c| B | C |
                          +---+---+---+---+

            In this example, the CPC has two crypto adapters c1 and c2. For
            simplicity of the example, we assume these crypto adapters support
            only 4 crypto domains.

            Partition A uses only adapter c1 and has domain 0 in
            'control-usage' access (indicated by an upper case letter 'A' in
            the corresponding cell) and has domain 1 in 'control' access
            (indicated by a lower case letter 'a' in the corresponding cell).

            Partition B uses only adapter c2 and has domain 0 in 'control'
            access and domains 1 and 2 in 'control-usage' access.

            Partition C uses both adapters, and has domains 0 and 1 in
            'control' access and domain 3 in 'control-usage' access.

            The domains free for usage in this example are shown in the
            following table, for each combination of crypto adapters to be
            investigated:

            ===============  ======================
            crypto_adapters  domains free for usage
            ===============  ======================
            c1               1, 2
            c2               0
            c1, c2           (empty list)
            ===============  ======================

        **Experimental:** This method has been added in v0.14.0 and is
        currently considered experimental. Its interface may change
        incompatibly. Once the interface remains stable, this experimental
        marker will be removed.

        Authorization requirements:

        * Object-access permission to this CPC.
        * Object-access permission to all of its Partitions.
        * Object-access permission to all of its crypto Adapters.

        Parameters:

          crypto_adapters (:term:`iterable` of :class:`~zhmcclient.Adapter`):
            The crypto :term:`Adapters <Adapter>` to be investigated.

            `None` means to investigate all crypto adapters of this CPC.

        Returns:

          A sorted list of domain index numbers (integers) of the crypto
          domains that are free for usage on the specified crypto adapters.

          Returns `None`, if ``crypto_adapters`` was an empty list or if
          ``crypto_adapters`` was `None` and the CPC has no crypto adapters.

        Raises:

          :exc:`~zhmcclient.HTTPError`
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
        """
        if crypto_adapters is None:
            crypto_adapters = self.adapters.findall(type='crypto')

        if not crypto_adapters:
            # No crypto adapters were specified or defaulted.
            return None

        # We determine the maximum number of crypto domains independently
        # of the partitions, because (1) it is possible that no partition
        # has a crypto configuration and (2) further down we want the inner
        # loop to be on the crypto adapters because accessing them multiple
        # times does not drive additional HMC operations.
        max_domains = None  # maximum number of domains across all adapters
        for ca in crypto_adapters:
            if max_domains is None:
                max_domains = ca.maximum_crypto_domains
            else:
                max_domains = min(ca.maximum_crypto_domains, max_domains)

        used_domains = set()  # Crypto domains used in control-usage mode
        partitions = self.partitions.list(full_properties=True)
        for partition in partitions:
            crypto_config = partition.get_property('crypto-configuration')
            if crypto_config:
                adapter_uris = crypto_config['crypto-adapter-uris']
                domain_configs = crypto_config['crypto-domain-configurations']
                for ca in crypto_adapters:
                    if ca.uri in adapter_uris:
                        used_adapter_domains = list()
                        for dc in domain_configs:
                            if dc['access-mode'] == 'control-usage':
                                used_adapter_domains.append(dc['domain-index'])
                        used_domains.update(used_adapter_domains)

        all_domains = set(range(0, max_domains))
        free_domains = all_domains - used_domains
        return sorted(list(free_domains))


Instruction:
Can you create a Python 3 function that
sets the power save setting of this CPC. The current power save setting in effect for a CPC is described in the "cpc-power-saving" property of the CPC. This method performs the HMC operation "Set CPC Power Save". It requires that the feature "Automate/advanced management suite" (FC 0020) is installed and enabled, and fails otherwise. This method will also fail if the CPC is under group control. Whether a CPC currently allows this method is described in the "cpc-power-save-allowed" property of the CPC. Authorization requirements: * Object-access permission to this CPC. * Task permission for the "Power Save" task. Parameters: power_saving (:term:`string`): The new power save setting, with the possible values: * "high-performance" - The power consumption and performance of the CPC are not reduced. This is the default setting. * "low-power" - Low power consumption for all components of the CPC enabled for power saving. * "custom" - Components may have their own settings changed individually. No component settings are actually changed when this mode is entered. wait_for_completion (bool): Boolean controlling whether this method should wait for completion of the requested asynchronous HMC operation, as follows: * If `True`, this method will wait for completion of the asynchronous job performing the operation. * If `False`, this method will return immediately once the HMC has accepted the request to perform the operation. operation_timeout (:term:`number`): Timeout in seconds, for waiting for completion of the asynchronous job performing the operation. The special value 0 means that no timeout is set. `None` means that the default async operation timeout of the session is used. If the timeout expires when `wait_for_completion=True`, a :exc:`~zhmcclient.OperationTimeout` is raised. Returns: `None` or :class:`~zhmcclient.Job`: If `wait_for_completion` is `True`, returns `None`. If `wait_for_completion` is `False`, returns a :class:`~zhmcclient.Job` object representing the asynchronously executing job on the HMC. Raises: :exc:`~zhmcclient.HTTPError`: See the HTTP status and reason codes of operation "Set CPC Power Save" in the :term:`HMC API` book. :exc:`~zhmcclient.ParseError` :exc:`~zhmcclient.AuthError` :exc:`~zhmcclient.ConnectionError` :exc:`~zhmcclient.OperationTimeout`: The timeout expired while waiting for completion of the operation.

Response:
def set_power_save(self, power_saving, wait_for_completion=True,
                       operation_timeout=None):
        """
        Set the power save setting of this CPC.

        The current power save setting in effect for a CPC is described in the
        "cpc-power-saving" property of the CPC.

        This method performs the HMC operation "Set CPC Power Save". It
        requires that the feature "Automate/advanced management suite"
        (FC 0020) is installed and enabled, and fails otherwise.

        This method will also fail if the CPC is under group control.

        Whether a CPC currently allows this method is described in the
        "cpc-power-save-allowed" property of the CPC.

        Authorization requirements:

        * Object-access permission to this CPC.
        * Task permission for the "Power Save" task.

        Parameters:

          power_saving (:term:`string`):
            The new power save setting, with the possible values:

            * "high-performance" - The power consumption and performance of
              the CPC are not reduced. This is the default setting.
            * "low-power" - Low power consumption for all components of the
              CPC enabled for power saving.
            * "custom" - Components may have their own settings changed
              individually. No component settings are actually changed when
              this mode is entered.

          wait_for_completion (bool):
            Boolean controlling whether this method should wait for completion
            of the requested asynchronous HMC operation, as follows:

            * If `True`, this method will wait for completion of the
              asynchronous job performing the operation.

            * If `False`, this method will return immediately once the HMC has
              accepted the request to perform the operation.

          operation_timeout (:term:`number`):
            Timeout in seconds, for waiting for completion of the asynchronous
            job performing the operation. The special value 0 means that no
            timeout is set. `None` means that the default async operation
            timeout of the session is used. If the timeout expires when
            `wait_for_completion=True`, a
            :exc:`~zhmcclient.OperationTimeout` is raised.

        Returns:

          `None` or :class:`~zhmcclient.Job`:

            If `wait_for_completion` is `True`, returns `None`.

            If `wait_for_completion` is `False`, returns a
            :class:`~zhmcclient.Job` object representing the asynchronously
            executing job on the HMC.

        Raises:

          :exc:`~zhmcclient.HTTPError`: See the HTTP status and reason codes of
            operation "Set CPC Power Save" in the :term:`HMC API` book.
          :exc:`~zhmcclient.ParseError`
          :exc:`~zhmcclient.AuthError`
          :exc:`~zhmcclient.ConnectionError`
          :exc:`~zhmcclient.OperationTimeout`: The timeout expired while
            waiting for completion of the operation.
        """
        body = {'power-saving': power_saving}
        result = self.manager.session.post(
            self.uri + '/operations/set-cpc-power-save',
            body,
            wait_for_completion=wait_for_completion,
            operation_timeout=operation_timeout)
        if wait_for_completion:
            # The HMC API book does not document what the result data of the
            # completed job is. It turns out that the completed job has this
            # dictionary as its result data:
            #    {'message': 'Operation executed successfully'}
            # We transform that to None.
            return None
        return result