.. _cred_providers:

Credential Providers
====================

These library interfaces are used to deal with allocating credentials on demand
either dynamically by calling keystone to allocate new credentials, or from
a list of preprovisioned credentials. These 2 modules are implementations of
the same abstract credential providers class and can be used interchangably.
However, each implementation has some additional parameters that are used to
influence the behavior of the modules. The API reference at the bottom of this
doc shows the interface definitions for both modules, however that may be a bit
opaque. You can see some examples of how to leverage this interface below.

Initialization Example
----------------------
This example is from Tempest itself (from tempest/common/credentials_factory.py
just modified slightly) and is how it initializes the credential provider based
on config::

  from tempest import config
  from tempest.lib.common import dynamic_creds
  from tempest.lib.common import preprov_creds

  CONF = config.CONF

  def get_credentials_provider(name, network_resources=None,
                               force_tenant_isolation=False,
                               identity_version=None):
      # If a test requires a new account to work, it can have it via forcing
      # dynamic credentials. A new account will be produced only for that test.
      # In case admin credentials are not available for the account creation,
      # the test should be skipped else it would fail.
      identity_version = identity_version or CONF.identity.auth_version
      if CONF.auth.use_dynamic_credentials or force_tenant_isolation:
          admin_creds = get_configured_admin_credentials(
              fill_in=True, identity_version=identity_version)
          return dynamic_creds.DynamicCredentialProvider(
              name=name,
              network_resources=network_resources,
              identity_version=identity_version,
              admin_creds=admin_creds,
              identity_admin_domain_scope=CONF.identity.admin_domain_scope,
              identity_admin_role=CONF.identity.admin_role,
              extra_roles=CONF.auth.tempest_roles,
              neutron_available=CONF.service_available.neutron,
              project_network_cidr=CONF.network.project_network_cidr,
              project_network_mask_bits=CONF.network.project_network_mask_bits,
              public_network_id=CONF.network.public_network_id,
              create_networks=(CONF.auth.create_isolated_networks and not
                               CONF.network.shared_physical_network),
              resource_prefix=CONF.resources_prefix,
              credentials_domain=CONF.auth.default_credentials_domain_name,
              admin_role=CONF.identity.admin_role,
              identity_uri=CONF.identity.uri_v3,
              identity_admin_endpoint_type=CONF.identity.v3_endpoint_type)
      else:
          if CONF.auth.test_accounts_file:
              # Most params are not relevant for pre-created accounts
              return preprov_creds.PreProvisionedCredentialProvider(
                  name=name, identity_version=identity_version,
                  accounts_lock_dir=lockutils.get_lock_path(CONF),
                  test_accounts_file=CONF.auth.test_accounts_file,
                  object_storage_operator_role=CONF.object_storage.operator_role,
                  object_storage_reseller_admin_role=reseller_admin_role,
                  credentials_domain=CONF.auth.default_credentials_domain_name,
                  admin_role=CONF.identity.admin_role,
                  identity_uri=CONF.identity.uri_v3,
                  identity_admin_endpoint_type=CONF.identity.v3_endpoint_type)
          else:
              raise exceptions.InvalidConfiguration(
                  'A valid credential provider is needed')

This function just returns an initialized credential provider class based on the
config file. The consumer of this function treats the output as the same
regardless of whether it's a dynamic or preprovisioned provider object.

Dealing with Credentials
------------------------

Once you have a credential provider object created the access patterns for
allocating and removing credentials are the same across both the dynamic
and preprovisioned credentials. These are defined in the abstract
CredentialProvider class. At a high level the credentials provider enables
you to get 3 basic types of credentials at once (per object): a primary, alt,
and admin. You're also able to allocate a credential by role. These credentials
are tracked by the provider object and delete must manually be called otherwise
the created resources will not be deleted (or returned to the pool in the case
of preprovisioned creds)

Examples
''''''''

Continuing from the example above, to allocate credentials by the 3 basic types
you can do the following::

  provider = get_credentials_provider('my_tests')
  primary_creds = provider.get_primary_creds()
  alt_creds = provider.get_alt_creds()
  admin_creds = provider.get_admin_creds()
  # Make sure to delete the credentials when you're finished
  provider.clear_creds()

To create and interact with credentials by role you can do the following::

  provider = get_credentials_provider('my_tests')
  my_role_creds = provider.get_creds_by_role({'roles': ['my_role']})
  # provider.clear_creds() will clear all creds including those allocated by
  # role
  provider.clear_creds()

When multiple roles are specified a set of creds with all the roles assigned
will be allocated::

  provider = get_credentials_provider('my_tests')
  my_role_creds = provider.get_creds_by_role({'roles': ['my_role',
                                                        'my_other_role']})
  # provider.clear_creds() will clear all creds including those allocated by
  # role
  provider.clear_creds()

If you need multiple sets of credentials with the same roles you can also do
this by leveraging the ``force_new`` kwarg::

  provider = get_credentials_provider('my_tests')
  my_role_creds = provider.get_creds_by_role({'roles': ['my_role']})
  my_role_other_creds = provider.get_creds_by_role({'roles': ['my_role']},
                                                   force_new=True)
  # provider.clear_creds() will clear all creds including those allocated by
  # role
  provider.clear_creds()

API Reference
=============

------------------------------
The dynamic credentials module
------------------------------

.. automodule:: tempest.lib.common.dynamic_creds
   :members:

--------------------------------------
The pre-provisioned credentials module
--------------------------------------

.. automodule:: tempest.lib.common.preprov_creds
   :members:
