def facts(params, check_mode):
    """
    Return facts about the crypto configuration of the partition.

    Raises:
      ParameterError: An issue with the module parameters.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    partition_name = params['partition_name']
    faked_session = params.get('faked_session', None)  # No default specified

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        cpc = client.cpcs.find(name=cpc_name)
        partition = cpc.partitions.find(name=partition_name)
        # The default exception handling is sufficient for the above.

        # Determine all crypto adapters of any crypto type
        filter_args = {
            'adapter-family': 'crypto',
        }
        all_adapters = cpc.adapters.list(filter_args=filter_args,
                                         full_properties=True)

        result = get_partition_config(partition, all_adapters)

        return False, result, None

    finally:
        session.logoff()
def facts(params, check_mode):
    """
    Identify the target CPC and return facts about the target CPC and its
    child resources.

    Raises:
      ParameterError: An issue with the module parameters.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['name']
    faked_session = params.get('faked_session', None)  # No default specified

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        cpc = client.cpcs.find(name=cpc_name)
        # The default exception handling is sufficient for the above.

        cpc.pull_full_properties()
        result = cpc.properties

        partitions = cpc.partitions.list()
        adapters = cpc.adapters.list()

        result['partitions'] = [p.properties for p in partitions]
        result['adapters'] = [a.properties for a in adapters]

        return False, result

    finally:
        session.logoff()
Exemplo n.º 3
0
def ensure_absent(params, check_mode):
    """
    Ensure that the storage volume does not exist.

    Raises:
      ParameterError: An issue with the module parameters.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    storage_group_name = params['storage_group_name']
    storage_volume_name = params['name']
    faked_session = params.get('faked_session', None)

    changed = False
    result = {}

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        console = client.consoles.console
        cpc = client.cpcs.find(name=cpc_name)
        storage_group = console.storage_groups.find(name=storage_group_name)
        # The default exception handling is sufficient for the above.

        sg_cpc = storage_group.cpc
        if sg_cpc.uri != cpc.uri:
            raise ParameterError(
                "Storage group {!r} is not associated with the specified "
                "CPC %r, but with CPC %r.".format(storage_group_name, cpc.name,
                                                  sg_cpc.name))

        try:
            storage_volume = storage_group.storage_volumes.find(
                name=storage_volume_name)
        except zhmcclient.NotFound:
            return changed, result
        except zhmcclient.NoUniqueMatch:
            # The name of storage volumes within their storage group is not
            # enforced to be unique.
            raise

        if not check_mode:
            storage_volume.delete()
        changed = True

        return changed, result

    finally:
        session.logoff()
Exemplo n.º 4
0
def ensure_absent(params, check_mode):
    """
    Ensure that the storage group does not exist.

    Raises:
      ParameterError: An issue with the module parameters.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    storage_group_name = params['name']
    faked_session = params.get('faked_session', None)

    changed = False
    result = {}

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        console = client.consoles.console
        cpc = client.cpcs.find(name=cpc_name)
        # The default exception handling is sufficient for the above.

        try:
            storage_group = console.storage_groups.find(
                name=storage_group_name)
        except zhmcclient.NotFound:
            return changed, result

        sg_cpc = storage_group.cpc
        if sg_cpc.uri != cpc.uri:
            raise ParameterError(
                "Storage group {!r} is not associated with the specified "
                "CPC %r, but with CPC %r.".format(storage_group_name, cpc.name,
                                                  sg_cpc.name))

        if not check_mode:
            partitions = storage_group.list_attached_partitions()
            for part in partitions:
                # This will raise HTTPError(409) if the partition is in one of
                # the transitional states ('starting', 'stopping').
                part.detach_storage_group(storage_group)
            storage_group.delete()
        changed = True

        return changed, result

    finally:
        session.logoff()
def facts(params, check_mode):
    """
    Return partition facts.

    Raises:
      ParameterError: An issue with the module parameters.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    partition_name = params['name']
    faked_session = params.get('faked_session', None)

    changed = False
    result = {}

    try:
        # The default exception handling is sufficient for this code

        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        cpc = client.cpcs.find(name=cpc_name)

        partition = cpc.partitions.find(name=partition_name)
        partition.pull_full_properties()

        # Get the child elements of the partition

        hbas_prop = list()
        if partition.hbas is not None:
            for hba in partition.hbas.list(full_properties=True):
                hbas_prop.append(hba.properties)
        partition.properties['hbas'] = hbas_prop

        nics_prop = list()
        for nic in partition.nics.list(full_properties=True):
            nics_prop.append(nic.properties)
        partition.properties['nics'] = nics_prop

        vf_prop = list()
        for vf in partition.virtual_functions.list(full_properties=True):
            vf_prop.append(vf.properties)
        partition.properties['virtual-functions'] = vf_prop

        result = partition.properties
        return changed, result

    finally:
        session.logoff()
Exemplo n.º 6
0
def ensure_detached(params, check_mode):
    """
    Ensure that the storage group is detached from the partition.

    Raises:
      ParameterError: An issue with the module parameters.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    storage_group_name = params['storage_group_name']
    partition_name = params['partition_name']
    faked_session = params.get('faked_session', None)

    changed = False
    attached = None

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        console = client.consoles.console
        cpc = client.cpcs.find(name=cpc_name)
        storage_group = console.storage_groups.find(name=storage_group_name)
        partition = cpc.partitions.find(name=partition_name)
        # The default exception handling is sufficient for the above.

        attached_partitions = storage_group.list_attached_partitions(
            name=partition_name)

        if attached_partitions:
            # The storage group is attached to the partition
            assert len(attached_partitions) == 1
            assert attached_partitions[0].name == partition_name
            attached = True
            if not check_mode:
                partition.detach_storage_group(storage_group)
                attached = False
            changed = True
        else:
            # The storage group is already detached from the partition
            attached = False

        result = dict(attached=attached)

        return changed, result

    finally:
        session.logoff()
def ensure_set(params, check_mode):
    """
    Identify the target CPC and ensure that the specified properties are set on
    the target CPC.

    Raises:
      ParameterError: An issue with the module parameters.
      Error: Other errors during processing.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    # Note: Defaults specified in argument_spec will be set in params dict
    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['name']
    faked_session = params.get('faked_session', None)  # No default specified

    changed = False

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        cpc = client.cpcs.find(name=cpc_name)
        # The default exception handling is sufficient for the above.

        cpc.pull_full_properties()
        result = cpc.properties
        update_props = process_properties(cpc, params)
        if update_props:
            if not check_mode:
                cpc.update_properties(update_props)
            # Some updates of CPC properties are not reflected in a new
            # retrieval of properties until after a few seconds (usually the
            # second retrieval).
            # Therefore, we construct the modified result based upon the input
            # changes, and not based upon newly retrieved properties.
            result.update(update_props)
            changed = True

        partitions = cpc.partitions.list()
        adapters = cpc.adapters.list()

        result['partitions'] = [p.properties for p in partitions]
        result['adapters'] = [a.properties for a in adapters]

        return changed, result

    finally:
        session.logoff()
Exemplo n.º 8
0
def facts(params, check_mode):
    """
    Return facts about a storage group and its storage volumes and virtual
    storage resources.

    Raises:
      ParameterError: An issue with the module parameters.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    storage_group_name = params['name']
    expand = params['expand']
    faked_session = params.get('faked_session', None)

    changed = False
    result = {}

    try:
        # The default exception handling is sufficient for this code

        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        console = client.consoles.console
        cpc = client.cpcs.find(name=cpc_name)

        storage_group = console.storage_groups.find(name=storage_group_name)
        storage_group.pull_full_properties()

        sg_cpc = storage_group.cpc
        if sg_cpc.uri != cpc.uri:
            raise ParameterError(
                "Storage group {!r} is not associated with the specified "
                "CPC %r, but with CPC %r.".format(storage_group_name, cpc.name,
                                                  sg_cpc.name))

        add_artificial_properties(storage_group, expand)
        result = storage_group.properties

        return changed, result

    finally:
        session.logoff()
def ensure_absent(params, check_mode):
    """
    Ensure that the virtual function does not exist.

    Raises:
      ParameterError: An issue with the module parameters.
      StatusError: An issue with the partition status.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    partition_name = params['partition_name']
    vfunction_name = params['name']
    faked_session = params.get('faked_session', None)

    changed = False
    result = {}

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        cpc = client.cpcs.find(name=cpc_name)
        partition = cpc.partitions.find(name=partition_name)
        # The default exception handling is sufficient for the above.

        try:
            vfunction = partition.virtual_functions.find(name=vfunction_name)
        except zhmcclient.NotFound:
            return changed, result

        if not check_mode:
            vfunction.delete()
        changed = True

        return changed, result

    finally:
        session.logoff()
Exemplo n.º 10
0
def ensure_absent(params, check_mode):
    """
    Ensure that the specified Hipersockets adapter does not exist.

    Raises:
      ParameterError: An issue with the module parameters.
      Error: Other errors during processing.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    # Note: Defaults specified in argument_spec will be set in params dict
    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    adapter_name = params['name']
    faked_session = params.get('faked_session', None)  # No default specified

    changed = False
    result = {}

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        cpc = client.cpcs.find(name=cpc_name)
        # The default exception handling is sufficient for the above.

        try:
            adapter = cpc.adapters.find(name=adapter_name)
        except zhmcclient.NotFound:
            return changed, result

        if not check_mode:
            adapter.delete()
        changed = True

        return changed, result

    finally:
        session.logoff()
Exemplo n.º 11
0
def facts(params, check_mode):
    """
    Return facts about a user and its storage volumes and virtual
    storage resources.

    Raises:
      ParameterError: An issue with the module parameters.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    user_name = params['name']
    expand = params['expand']
    faked_session = params.get('faked_session', None)

    changed = False
    result = {}

    try:
        # The default exception handling is sufficient for this code

        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        console = client.consoles.console

        user = console.users.find(name=user_name)
        user.pull_full_properties()

        add_artificial_properties(console, user, expand, check_mode)
        result = user.properties

        return changed, result

    finally:
        session.logoff()
Exemplo n.º 12
0
def ensure_absent(params, check_mode):
    """
    Ensure that the user does not exist.

    Raises:
      ParameterError: An issue with the module parameters.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    user_name = params['name']
    faked_session = params.get('faked_session', None)

    changed = False
    result = {}

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        console = client.consoles.console
        # The default exception handling is sufficient for the above.

        try:
            user = console.users.find(name=user_name)
        except zhmcclient.NotFound:
            return changed, result

        if not check_mode:
            user.delete()
        changed = True

        return changed, result

    finally:
        session.logoff()
Exemplo n.º 13
0
def ensure_set(params, check_mode):
    """
    Identify the target adapter (that must exist) and ensure that the specified
    properties are set on the adapter.

    Raises:
      ParameterError: An issue with the module parameters.
      Error: Other errors during processing.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    # Note: Defaults specified in argument_spec will be set in params dict
    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    adapter_name = params['name']
    adapter_match = params['match']
    faked_session = params.get('faked_session', None)  # No default specified

    changed = False

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        cpc = client.cpcs.find(name=cpc_name)
        adapter = identify_adapter(cpc, adapter_name, adapter_match)
        # The default exception handling is sufficient for the above.

        adapter.pull_full_properties()
        result = adapter.properties

        # It was identified by name or match properties, so it does exist.
        # Update its properties and change adapter and crypto type, if
        # needed.
        create_props, update_props, chg_adapter_type, chg_crypto_type = \
            process_properties(adapter, params)

        if update_props:
            if not check_mode:
                adapter.update_properties(update_props)
            else:
                result.update(update_props)  # from input values
            changed = True

        if chg_adapter_type:
            if not check_mode:
                adapter.change_adapter_type(chg_adapter_type)
            else:
                result['type'] = chg_adapter_type
            changed = True

        if chg_crypto_type:
            if not check_mode:
                adapter.change_crypto_type(chg_crypto_type)
            else:
                result['crypto-type'] = chg_crypto_type
            changed = True

        if changed and not check_mode:
            adapter.pull_full_properties()
            result = adapter.properties  # from actual values

        ports = adapter.ports.list()
        result_ports = list()
        for port in ports:
            # TODO: Disabling the following line mitigates the recent issue
            #       with HTTP error 404,4 when retrieving port properties.
            # port.pull_full_properties()
            result_ports.append(port.properties)
        result['ports'] = result_ports

        return changed, result

    finally:
        session.logoff()
Exemplo n.º 14
0
def ensure_present(params, check_mode):
    """
    Ensure that the specified Hipersockets adapter exists and has the
    specified properties set.

    Raises:
      ParameterError: An issue with the module parameters.
      Error: Other errors during processing.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    # Note: Defaults specified in argument_spec will be set in params dict
    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    adapter_name = params['name']
    faked_session = params.get('faked_session', None)  # No default specified

    changed = False

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        cpc = client.cpcs.find(name=cpc_name)
        # The default exception handling is sufficient for the above.

        try:
            adapter = cpc.adapters.find(name=adapter_name)
        except zhmcclient.NotFound:
            adapter = None

        if not adapter:
            # It does not exist. The only possible adapter type
            # that can be created is a Hipersockets adapter, but before
            # creating one we check the 'type' input property to verify that
            # the intention is really Hipersockets creation, and not just a
            # mispelled name.
            input_props = params.get('properties', None)
            if input_props is None:
                adapter_type = None
            else:
                adapter_type = input_props.get('type', None)
            if adapter_type is None:
                raise ParameterError(
                    "Input property 'type' missing when creating "
                    "Hipersockets adapter {!r} (must specify 'hipersockets')".
                    format(adapter_name))
            if adapter_type != 'hipersockets':
                raise ParameterError(
                    "Input property 'type' specifies {!r} when creating "
                    "Hipersockets adapter {!r} (must specify 'hipersockets').".
                    format(adapter_type, adapter_name))

            create_props, update_props = process_properties(adapter, params)

            # This is specific to Hipersockets: There are no update-only
            # properties, so any remaining such property is an input error
            invalid_update_props = {}
            for name in update_props:
                if name not in create_props:
                    invalid_update_props[name] = update_props[name]
            if invalid_update_props:
                raise ParameterError(
                    "Invalid input properties specified when creating "
                    "Hipersockets adapter {!r}: {!r}".format(
                        adapter_name, invalid_update_props))

            # While the 'type' input property is required for verifying
            # the intention, it is not allowed as input for the
            # Create Hipersocket HMC operation.
            del create_props['type']

            if not check_mode:
                adapter = cpc.adapters.create_hipersocket(create_props)
                adapter.pull_full_properties()
                result = adapter.properties  # from actual values
            else:
                adapter = None
                result = dict()
                result.update(create_props)  # from input values
            changed = True
        else:
            # It does exist.
            # Update its properties and change adapter and crypto type, if
            # needed.

            adapter.pull_full_properties()
            result = adapter.properties

            create_props, update_props, chg_adapter_type, chg_crypto_type = \
                process_properties(adapter, params)

            if update_props:
                if not check_mode:
                    adapter.update_properties(update_props)
                else:
                    result.update(update_props)  # from input values
                changed = True

            if chg_adapter_type:
                if not check_mode:
                    adapter.change_adapter_type(chg_adapter_type)
                else:
                    result['type'] = chg_adapter_type
                changed = True

            if chg_crypto_type:
                if not check_mode:
                    adapter.change_crypto_type(chg_crypto_type)
                else:
                    result['crypto-type'] = chg_crypto_type
                changed = True

            if changed and not check_mode:
                adapter.pull_full_properties()
                result = adapter.properties  # from actual values

        if adapter:
            ports = adapter.ports.list()
            result_ports = list()
            for port in ports:
                port.pull_full_properties()
                result_ports.append(port.properties)
            result['ports'] = result_ports
        else:
            # For now, we return no ports when creating in check mode
            result['ports'] = dict()

        return changed, result

    finally:
        session.logoff()
def ensure_stopped(params, check_mode):
    """
    Ensure that the partition exists, is stopped, and has the specified
    properties.

    Raises:
      ParameterError: An issue with the module parameters.
      StatusError: An issue with the partition status.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    partition_name = params['name']
    faked_session = params.get('faked_session', None)

    changed = False
    result = {}

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        cpc = client.cpcs.find(name=cpc_name)
        # The default exception handling is sufficient for the above.

        try:
            partition = cpc.partitions.find(name=partition_name)
            partition.pull_full_properties()
        except zhmcclient.NotFound:
            partition = None

        if not partition:
            # It does not exist. Create it and update it if there are
            # update-only properties.
            if not check_mode:
                create_props, update_props, stop, crypto_changes = \
                    process_properties(cpc, partition, params)
                partition = cpc.partitions.create(create_props)
                update2_props = {}
                for name in update_props:
                    if name not in create_props:
                        update2_props[name] = update_props[name]
                if update2_props:
                    partition.update_properties(update2_props)
                if crypto_changes:
                    change_crypto_config(partition, crypto_changes, check_mode)
            changed = True
        else:
            # It exists. Stop it and update its properties.
            create_props, update_props, stop, crypto_changes = \
                process_properties(cpc, partition, params)
            changed |= stop_partition(partition, check_mode)
            if update_props:
                if not check_mode:
                    partition.update_properties(update_props)
                changed = True
            if crypto_changes:
                changed |= change_crypto_config(partition, crypto_changes,
                                                check_mode)

        if partition and not check_mode:
            partition.pull_full_properties()
            status = partition.get_property('status')
            if status not in ('stopped'):
                raise StatusError(
                    "Could not get partition {!r} into a stopped state, "
                    "status is: {!r}".format(partition.name, status))

        if partition:
            result = partition.properties

        return changed, result

    finally:
        session.logoff()
def ensure_active(params, check_mode):
    """
    Ensure that the partition exists, is active or degraded, and has the
    specified properties.

    Raises:
      ParameterError: An issue with the module parameters.
      StatusError: An issue with the partition status.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    partition_name = params['name']
    faked_session = params.get('faked_session', None)

    changed = False
    result = {}

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        cpc = client.cpcs.find(name=cpc_name)
        # The default exception handling is sufficient for the above.

        try:
            partition = cpc.partitions.find(name=partition_name)
            partition.pull_full_properties()
        except zhmcclient.NotFound:
            partition = None

        if not partition:
            # It does not exist. Create it and update it if there are
            # update-only properties.
            if not check_mode:
                create_props, update_props, stop, crypto_changes = \
                    process_properties(cpc, partition, params)
                partition = cpc.partitions.create(create_props)
                update2_props = {}
                for name in update_props:
                    if name not in create_props:
                        update2_props[name] = update_props[name]
                if update2_props:
                    partition.update_properties(update2_props)
                # We refresh the properties after the update, in case an
                # input property value gets changed (for example, the
                # partition does that with memory properties).
                partition.pull_full_properties()
                if crypto_changes:
                    change_crypto_config(partition, crypto_changes, check_mode)
            else:
                # TODO: Show props in module result also in check mode.
                pass
            changed = True
        else:
            # It exists. Stop if needed due to property update requirements,
            # or wait for an updateable partition status, and update its
            # properties.
            create_props, update_props, stop, crypto_changes = \
                process_properties(cpc, partition, params)
            if update_props:
                if not check_mode:
                    if stop:
                        stop_partition(partition, check_mode)
                    else:
                        wait_for_transition_completion(partition)
                    partition.update_properties(update_props)
                    # We refresh the properties after the update, in case an
                    # input property value gets changed (for example, the
                    # partition does that with memory properties).
                    partition.pull_full_properties()
                else:
                    # TODO: Show updated props in mod.result also in chk.mode
                    pass
                changed = True
            if crypto_changes:
                changed |= change_crypto_config(partition, crypto_changes,
                                                check_mode)

        if partition:
            changed |= start_partition(partition, check_mode)

        if partition and not check_mode:
            partition.pull_full_properties()
            status = partition.get_property('status')
            if status not in ('active', 'degraded'):
                raise StatusError(
                    "Could not get partition {!r} into an active state, "
                    "status is: {!r}".format(partition.name, status))

        if partition:
            result = partition.properties

        return changed, result

    finally:
        session.logoff()
def ensure_detached(params, check_mode):
    """
    Ensure that the target partition has no adapters and no domains attached.

    Raises:
      ParameterError: An issue with the module parameters.
      Error: Other errors during processing.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    # Note: Defaults specified in argument_spec will be set in params dict
    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    partition_name = params['partition_name']
    faked_session = params.get('faked_session', None)  # No default specified

    changed = False
    result = dict()
    result_changes = dict()

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        cpc = client.cpcs.find(name=cpc_name)
        partition = cpc.partitions.find(name=partition_name)
        # The default exception handling is sufficient for the above.

        # Determine all crypto adapters of any crypto type
        filter_args = {
            'adapter-family': 'crypto',
        }
        all_adapters = cpc.adapters.list(filter_args=filter_args,
                                         full_properties=True)

        cc = partition.get_property('crypto-configuration')
        # The 'crypto-configuration' property is None or:
        # {
        #   'crypto-adapter-uris': ['/api/...', ...],
        #   'crypto-domain-configurations': [
        #     {'domain-index': 15, 'access-mode': 'control-usage'},
        #     ...
        #   ]
        # }
        if cc:
            attached_adapter_uris = cc['crypto-adapter-uris']
            remove_adapters = []
            remove_adapter_names = []
            for a in all_adapters:
                if a.uri in attached_adapter_uris:
                    remove_adapters.append(a)
                    remove_adapter_names.append(a.name)

            remove_domains = []
            for dc in cc['crypto-domain-configurations']:
                di = dc['domain-index']
                remove_domains.append(di)

            LOGGER.debug(
                "Detaching adapters {!r} and domains {!r} from target "
                "partition {!r}".format(remove_adapter_names, remove_domains,
                                        partition.name))

            if not check_mode:
                try:
                    partition.decrease_crypto_config(remove_adapters,
                                                     remove_domains)
                except zhmcclient.Error as exc:
                    raise Error(
                        "Detaching adapters {!r} and domains {!r} from "
                        "target partition {!r} failed: {}".format(
                            remove_adapter_names, remove_domains,
                            partition.name, exc))

            changed = True
            result_changes['removed-adapters'] = remove_adapter_names
            result_changes['removed-domains'] = remove_domains

        if not check_mode:
            # This is not optimal because it does not produce a result
            # in check mode, but because the actual config is determined,
            # instead of the artificially calculated one, it seems better
            # to return no config than the unchanged actual config.
            result.update(get_partition_config(partition, all_adapters))

        return changed, result, result_changes

    finally:
        session.logoff()
def ensure_present(params, check_mode):
    """
    Ensure that the virtual function exists and has the specified properties.

    Raises:
      ParameterError: An issue with the module parameters.
      StatusError: An issue with the partition status.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    partition_name = params['partition_name']
    vfunction_name = params['name']
    faked_session = params.get('faked_session', None)

    changed = False
    result = {}

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        cpc = client.cpcs.find(name=cpc_name)
        # The default exception handling is sufficient for the above.

        try:
            partition = cpc.partitions.find(name=partition_name)
        except zhmcclient.NotFound:
            if check_mode:
                # Once the partition is created, the virtual function  will
                # also need to be created. Therefore, we set changed.
                changed = True
                return changed, result
            raise

        try:
            vfunction = partition.virtual_functions.find(name=vfunction_name)
            vfunction.pull_full_properties()
        except zhmcclient.NotFound:
            vfunction = None

        if not vfunction:
            # It does not exist. Create it and update it if there are
            # update-only properties.
            if not check_mode:
                create_props, update_props, stop = process_properties(
                    partition, vfunction, params)
                vfunction = partition.virtual_functions.create(create_props)
                update2_props = {}
                for name in update_props:
                    if name not in create_props:
                        update2_props[name] = update_props[name]
                if update2_props:
                    vfunction.update_properties(update2_props)
                # We refresh the properties after the update, in case an
                # input property value gets changed (for example, the
                # partition does that with memory properties).
                vfunction.pull_full_properties()
            else:
                # TODO: Show props in module result also in check mode.
                pass
            changed = True
        else:
            # It exists. Stop the partition if needed due to the virtual
            # function property update requirements, or wait for an updateable
            # partition status, and update the virtual function properties.
            create_props, update_props, stop = process_properties(
                partition, vfunction, params)
            if update_props:
                if not check_mode:
                    # Virtual function properties can all be updated while the
                    # partition is active, therefore:
                    assert not stop
                    wait_for_transition_completion(partition)
                    vfunction.update_properties(update_props)
                    # We refresh the properties after the update, in case an
                    # input property value gets changed (for example, the
                    # partition does that with memory properties).
                    vfunction.pull_full_properties()
                else:
                    # TODO: Show updated props in mod.result also in chk.mode
                    pass
                changed = True

        if vfunction:
            result = vfunction.properties

        return changed, result

    finally:
        session.logoff()
Exemplo n.º 19
0
def ensure_present(params, check_mode):
    """
    Ensure that the storage volume is defined and has the specified properties.

    Raises:
      ParameterError: An issue with the module parameters.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    storage_group_name = params['storage_group_name']
    storage_volume_name = params['name']
    faked_session = params.get('faked_session', None)

    changed = False
    result = {}

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        console = client.consoles.console
        cpc = client.cpcs.find(name=cpc_name)
        storage_group = console.storage_groups.find(name=storage_group_name)
        # The default exception handling is sufficient for the above.

        sg_cpc = storage_group.cpc
        if sg_cpc.uri != cpc.uri:
            raise ParameterError(
                "Storage group {!r} is not associated with the specified "
                "CPC %r, but with CPC %r.".format(storage_group_name, cpc.name,
                                                  sg_cpc.name))

        try:
            storage_volume = storage_group.storage_volumes.find(
                name=storage_volume_name)
        except zhmcclient.NotFound:
            storage_volume = None
        except zhmcclient.NoUniqueMatch:
            # The name of storage volumes within their storage group is not
            # enforced to be unique.
            raise

        if storage_volume is None:
            # It does not exist. Create it and update it if there are
            # update-only properties.
            if not check_mode:
                create_props, update_props = \
                    process_properties(cpc, storage_group, storage_volume,
                                       params)
                storage_volume = storage_group.storage_volumes.create(
                    create_props)
                update2_props = {}
                for name in update_props:
                    if name not in create_props:
                        update2_props[name] = update_props[name]
                if update2_props:
                    storage_volume.update_properties(update2_props)
                # We refresh the properties after the update, in case an
                # input property value gets changed.
                storage_volume.pull_full_properties()
            else:
                # TODO: Show props in module result also in check mode.
                pass
            changed = True
        else:
            # It exists. Update its properties.
            storage_volume.pull_full_properties()
            create_props, update_props = \
                process_properties(cpc, storage_group, storage_volume, params)
            assert not create_props, \
                "Unexpected create_props: %r" % create_props
            if update_props:
                if not check_mode:
                    storage_volume.update_properties(update_props)
                    # We refresh the properties after the update, in case an
                    # input property value gets changed.
                    storage_volume.pull_full_properties()
                else:
                    # TODO: Show updated props in mod.result also in chk.mode
                    storage_volume.pull_full_properties()
                changed = True

        if not check_mode:
            assert storage_volume

        if storage_volume:
            add_artificial_properties(storage_volume)
            result = storage_volume.properties

        return changed, result

    finally:
        session.logoff()
Exemplo n.º 20
0
def ensure_present(params, check_mode):
    """
    Ensure that the storage group exists and has the specified properties.

    Storage volumes are not subject of this function, they are handled by the
    zhmc_storage_volume.py module.

    Raises:
      ParameterError: An issue with the module parameters.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    storage_group_name = params['name']
    expand = params['expand']
    faked_session = params.get('faked_session', None)

    changed = False
    result = {}

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        console = client.consoles.console
        cpc = client.cpcs.find(name=cpc_name)
        # The default exception handling is sufficient for the above.

        try:
            storage_group = console.storage_groups.find(
                name=storage_group_name)
        except zhmcclient.NotFound:
            storage_group = None

        if storage_group is None:
            # It does not exist. Create it and update it if there are
            # update-only properties.
            if not check_mode:
                create_props, update_props = \
                    process_properties(cpc, storage_group, params)
                storage_group = console.storage_groups.create(create_props)
                update2_props = {}
                for name in update_props:
                    if name not in create_props:
                        update2_props[name] = update_props[name]
                if update2_props:
                    storage_group.update_properties(update2_props)
                # We refresh the properties after the update, in case an
                # input property value gets changed.
                storage_group.pull_full_properties()
            else:
                # TODO: Show props in module result also in check mode.
                pass
            changed = True
        else:
            # It exists. Update its properties.
            storage_group.pull_full_properties()
            create_props, update_props = \
                process_properties(cpc, storage_group, params)
            assert not create_props, \
                "Unexpected create_props: %r" % create_props
            if update_props:
                if not check_mode:
                    storage_group.update_properties(update_props)
                    # We refresh the properties after the update, in case an
                    # input property value gets changed.
                    storage_group.pull_full_properties()
                else:
                    # TODO: Show updated props in mod.result also in chk.mode
                    pass
                changed = True

        if not check_mode:
            assert storage_group
            add_artificial_properties(storage_group, expand)
            result = storage_group.properties

        return changed, result

    finally:
        session.logoff()
Exemplo n.º 21
0
def ensure_present(params, check_mode):
    """
    Ensure that the user exists and has the specified properties.

    Storage volumes are not subject of this function, they are handled by the
    zhmc_storage_volume.py module.

    Raises:
      ParameterError: An issue with the module parameters.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    user_name = params['name']
    expand = params['expand']
    faked_session = params.get('faked_session', None)

    changed = False
    result = {}

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        console = client.consoles.console
        # The default exception handling is sufficient for the above.

        try:
            user = console.users.find(name=user_name)
        except zhmcclient.NotFound:
            user = None

        if user is None:
            # It does not exist. Create it and update it if there are
            # update-only properties.
            create_props, update_props = process_properties(
                console, user, params)
            update2_props = {}
            for name in update_props:
                if name not in create_props:
                    update2_props[name] = update_props[name]
            if not check_mode:
                user = console.users.create(create_props)
                if update2_props:
                    user.update_properties(update2_props)
                # We refresh the properties after the update, in case an
                # input property value gets changed.
                user.pull_full_properties()
            else:
                # Create a User object locally
                user = create_check_mode_user(console, create_props,
                                              update2_props)
            changed = True
        else:
            # It exists. Update its properties.
            user.pull_full_properties()
            create_props, update_props = process_properties(
                console, user, params)
            assert not create_props, \
                "Unexpected create_props: %r" % create_props
            if update_props:
                LOGGER.debug(
                    "Existing user {!r} needs to get properties updated: {!r}".
                    format(user_name, update_props))
                if not check_mode:
                    user.update_properties(update_props)
                    # We refresh the properties after the update, in case an
                    # input property value gets changed.
                    user.pull_full_properties()
                else:
                    # Update the local User object's properties
                    user.properties.update(update_props)
                changed = True

        assert user
        add_artificial_properties(console, user, expand, check_mode)
        result = user.properties

        return changed, result

    finally:
        session.logoff()
def ensure_attached(params, check_mode):
    """
    Ensure that the specified crypto adapters and crypto domains are attached
    to the target partition.

    Raises:
      ParameterError: An issue with the module parameters.
      Error: Other errors during processing.
      zhmcclient.Error: Any zhmcclient exception can happen.
    """

    # Note: Defaults specified in argument_spec will be set in params dict
    host = params['hmc_host']
    userid, password = get_hmc_auth(params['hmc_auth'])
    cpc_name = params['cpc_name']
    partition_name = params['partition_name']
    adapter_count = params['adapter_count']
    domain_range = params['domain_range']
    access_mode = params['access_mode']
    crypto_type = params['crypto_type']
    faked_session = params.get('faked_session', None)  # No default specified

    try:
        assert len(domain_range) == 2, \
            "len(domain_range)={}".format(len(domain_range))
        domain_range_lo = int(domain_range[0])
        domain_range_hi = int(domain_range[1])
    except (ValueError, AssertionError):
        raise ParameterError(
            "The 'domain_range' parameter must be a list containing two "
            "integer numbers, but is: {!r}".format(domain_range))

    hmc_crypto_type = CRYPTO_TYPES_MOD2HMC[crypto_type]
    hmc_access_mode = ACCESS_MODES_MOD2HMC[access_mode]

    changed = False
    result = dict()
    result_changes = dict()

    try:
        session = get_session(faked_session, host, userid, password)
        client = zhmcclient.Client(session)
        cpc = client.cpcs.find(name=cpc_name)
        partition = cpc.partitions.find(name=partition_name)
        # The default exception handling is sufficient for the above.

        # Determine all crypto adapters of the specified crypto type.
        filter_args = {
            'adapter-family': 'crypto',
            'crypto-type': hmc_crypto_type,
        }
        all_adapters = cpc.adapters.list(filter_args=filter_args,
                                         full_properties=True)
        if not all_adapters:
            raise Error(
                "No crypto adapters of type {!r} found on CPC {!r} ".format(
                    crypto_type, cpc_name))

        # All crypto adapters in a CPC have the same number of domains
        # (otherwise the concept of attaching domains across all attached
        # adapters cannot work). Therefore, the max number of domains can be
        # gathered from any adapter.
        max_domains = all_adapters[0].maximum_crypto_domains

        # Parameter checking on domain range.
        # (can be done only now because it requires the max_domains).
        if domain_range_hi == -1:
            domain_range_hi = max_domains - 1
        if domain_range_lo > domain_range_hi:
            raise ParameterError(
                "In the 'domain_range' parameter, the lower boundary (={}) "
                "of the range must be less than the higher boundary (={})".
                format(domain_range_lo, domain_range_hi))

        # Parameter checking on adapter count.
        # (can be done only now because it requires the number of adapters).
        if adapter_count == -1:
            adapter_count = len(all_adapters)
        if adapter_count < 1:
            raise ParameterError(
                "The 'adapter_count' parameter must be at least 1, but is: {}".
                format(adapter_count))
        if adapter_count > len(all_adapters):
            raise ParameterError(
                "The 'adapter_count' parameter must not exceed the number of "
                "{} crypto adapters of type {!r} in CPC {!r}, but is {}".
                format(len(all_adapters), crypto_type, cpc_name,
                       adapter_count))

        #
        # Get current crypto config of the target partition.
        #

        # Domains attached to the partition, as a dict with:
        #   key: domain index
        #   value: access mode
        attached_domains = dict()

        # Adapters attached to the partition, as a list of Adapter objects:
        attached_adapters = list()

        # Adapters not attached to the partition, as a list of Adapter objects:
        detached_adapters = list()

        _attached_adapter_uris = list()  # URIs of attached adapters
        cc = partition.get_property('crypto-configuration')
        if cc:
            _attached_adapter_uris = cc['crypto-adapter-uris']
            for dc in cc['crypto-domain-configurations']:
                di = int(dc['domain-index'])
                am = dc['access-mode']
                LOGGER.debug("Crypto config of partition {!r}: "
                             "Domain {} is attached in {!r} mode".format(
                                 partition.name, di, am))
                attached_domains[di] = am
        for a in all_adapters:
            if a.uri in _attached_adapter_uris:
                LOGGER.debug("Crypto config of partition {!r}: "
                             "Adapter {!r} is attached".format(
                                 partition.name, a.name))
                attached_adapters.append(a)
            else:
                LOGGER.debug("Crypto config of partition {!r}: "
                             "Adapter {!r} is not attached".format(
                                 partition.name, a.name))
                detached_adapters.append(a)
        del _attached_adapter_uris

        #
        # Get the current crypto config of all partitions of the CPC.
        #
        # This is needed because finding out whether an adapter has the right
        # domains available by simply attaching it to the target partition
        # and reacting to the returned status does not work for stopped
        # partitions.
        #

        # All partition of the CPC, as a dict:
        #   key: partition URI
        #   value: Partition object
        all_partitions = cpc.partitions.list()
        all_partitions = dict(
            zip([p.uri for p in all_partitions], all_partitions))

        # Crypto config of all partitions of the CPC, as a dict with:
        #   key: adapter URI
        #   value: dict:
        #     key: domain index (for attached domains)
        #     value: list of tuple(access mode, partition URI)
        all_crypto_config = dict()

        for p_uri in all_partitions:
            p = all_partitions[p_uri]
            cc = p.get_property('crypto-configuration')
            # The 'crypto-configuration' property is None or:
            # {
            #   'crypto-adapter-uris': ['/api/...', ...],
            #   'crypto-domain-configurations': [
            #     {'domain-index': 15, 'access-mode': 'control-usage'},
            #     ...
            #   ]
            # }
            if cc:
                _adapter_uris = cc['crypto-adapter-uris']
                for dc in cc['crypto-domain-configurations']:
                    di = int(dc['domain-index'])
                    am = dc['access-mode']
                    for a_uri in _adapter_uris:
                        if a_uri not in all_crypto_config:
                            all_crypto_config[a_uri] = dict()
                        domains_dict = all_crypto_config[a_uri]  # mutable
                        if di not in domains_dict:
                            domains_dict[di] = list()
                        domains_dict[di].append((am, p.uri))

        #
        # Determine the domains to be attached to the target partition
        #

        desired_domains = list(range(domain_range_lo, domain_range_hi + 1))
        add_domains = list()  # List of domain index numbers to be attached
        for di in desired_domains:
            if di not in attached_domains:
                # This domain is not attached to the target partition
                add_domains.append(di)
            elif attached_domains[di] != hmc_access_mode:
                # This domain is attached to the target partition but not in
                # the desired access mode. The access mode could be extended
                # from control to control+usage, but that is not implemented
                # by this code here.
                raise Error(
                    "Domain {} is currently attached in {!r} mode to target "
                    "partition {!r}, but requested was {!r} mode".format(
                        di, ACCESS_MODES_HMC2MOD[attached_domains[di]],
                        partition.name, access_mode))
            else:
                # This domain is attached to the target partition in the
                # desired access mode
                pass

        # Create the domain config structure for the domains to be attached
        add_domain_config = list()
        for di in add_domains:
            add_domain_config.append({
                'domain-index': di,
                'access-mode': hmc_access_mode
            })

        # Check that the domains to be attached to the partition are available
        # on the currently attached adapters
        for a in attached_adapters:
            domains_dict = all_crypto_config[a.uri]
            for di in add_domains:
                if di in domains_dict:
                    for am, p_uri in domains_dict[di]:
                        if am != 'control' and hmc_access_mode != 'control':
                            # Multiple attachments conflict only when both are
                            # in usage mode
                            p = all_partitions[p_uri]
                            raise Error(
                                "Domain {} cannot be attached in {!r} mode to "
                                "target partition {!r} because it is already "
                                "attached in {!r} mode to partition {!r}".
                                format(di, access_mode, partition.name,
                                       ACCESS_MODES_HMC2MOD[am], p.name))

        # Make sure the desired number of adapters is attached to the partition
        # and the desired domains are attached.
        # The HMC enforces the following for non-empty crypto configurations of
        # a partition:
        # - In the resulting config, the partition needs to have at least one
        #   adapter attached.
        # - In the resulting config, the partition needs to have at least one
        #   domain attached in usage mode.
        # As a result, on an empty crypto config, the first adapter and the
        # first domain(s) need to be attached at the same time.
        result_changes['added-adapters'] = []
        result_changes['added-domains'] = []
        missing_count = max(0, adapter_count - len(attached_adapters))
        assert missing_count <= len(detached_adapters), \
            "missing_count={}, len(detached_adapters)={}".\
            format(missing_count, len(detached_adapters))
        if missing_count == 0 and add_domain_config:
            # Adapters already sufficient, but domains to be attached

            LOGGER.debug(
                "Adapters sufficient - attaching domains {!r} in {!r} mode to "
                "target partition {!r}".format(add_domains, access_mode,
                                               partition.name))

            if not check_mode:
                try:
                    partition.increase_crypto_config([], add_domain_config)
                except zhmcclient.Error as exc:
                    raise Error(
                        "Attaching domains {!r} in {!r} mode to target "
                        "partition {!r} failed: {}".format(
                            add_domains, access_mode, partition.name, exc))

            changed = True
            result_changes['added-domains'].extend(add_domains)

        elif missing_count > 0:
            # Adapters need to be attached

            for adapter in detached_adapters:
                if missing_count == 0:
                    break

                # Check that the adapter has all needed domains available
                conflicting_domains = dict()
                if adapter.uri in all_crypto_config:
                    domains_dict = all_crypto_config[adapter.uri]
                    for di in desired_domains:
                        if di in domains_dict:
                            # The domain is already attached to some
                            # partition(s) in some access mode
                            for am, p_uri in domains_dict[di]:
                                if am == 'control':
                                    # An attachment in control mode does not
                                    # prevent additional attachments
                                    continue
                                if p_uri == partition.uri and \
                                        am == hmc_access_mode:
                                    # This is our target partition, and the
                                    # domain is already attached in the desired
                                    # mode.
                                    continue
                                p = all_partitions[p_uri]
                                conflicting_domains[di] = (am, p.name)

                if conflicting_domains:
                    LOGGER.debug(
                        "Skipping adapter {!r} because the following of its "
                        "domains are already attached to other partitions: "
                        "{!r}".format(adapter.name, conflicting_domains))
                    continue

                LOGGER.debug(
                    "Attaching adapter {!r} and domains {!r} in {!r} mode to "
                    "target partition {!r}".format(adapter.name, add_domains,
                                                   access_mode,
                                                   partition.name))

                if not check_mode:
                    try:
                        partition.increase_crypto_config([adapter],
                                                         add_domain_config)
                    except zhmcclient.Error as exc:
                        raise Error(
                            "Attaching adapter {!r} and domains {!r} in {!r} "
                            "mode to target partition {!r} failed: {}".format(
                                adapter.name, add_domains, access_mode,
                                partition.name, exc))

                changed = True
                result_changes['added-adapters'].append(adapter.name)
                result_changes['added-domains'].extend(add_domains)

                # Don't try to add again for next adapter:
                add_domain_config = []
                add_domains = []

                missing_count -= 1

            if missing_count > 0:
                # Because adapters may be skipped, it is possible that there
                # are not enough adapters
                raise Error(
                    "Did not find enough crypto adapters with attachable "
                    "domains - missing adapters: {}; Requested domains: {}, "
                    "Access mode: {}".format(missing_count, desired_domains,
                                             access_mode))

        if not check_mode:
            # This is not optimal because it does not produce a result
            # in check mode, but because the actual config is determined,
            # instead of the artificially calculated one, it seems better
            # to return no config than the unchanged actual config.
            result.update(get_partition_config(partition, all_adapters))

        return changed, result, result_changes

    finally:
        session.logoff()