diff --git a/barbicanclient/client.py b/barbicanclient/client.py index 6384f2cb..d4da6560 100644 --- a/barbicanclient/client.py +++ b/barbicanclient/client.py @@ -66,34 +66,35 @@ class Client(object): """ Barbican client object used to interact with barbican service. - :param session: An instance of keystoneclient.session.Session that + :param session: An instance of a keystoneclient Session that can be either authenticated, or not authenticated. When using a non-authenticated Session, you must provide some additional parameters. When no session is provided it will default to a non-authenticated Session. - :param endpoint: Barbican endpoint url. Required when a session is not - given, or when using a non-authentciated session. + :type session: keystoneclient.session.Session + :param str endpoint: Barbican endpoint url. Required when a session is + not given, or when using a non-authenticated session. When using an authenticated session, the client will attempt to get an endpoint from the session. - :param project_id: The project ID used for context in Barbican. + :param str project_id: The project ID used for context in Barbican. Required when a session is not given, or when using a non-authenticated session. When using an authenticated session, the project ID will be provided by the authentication mechanism. - :param verify: When a session is not given, the client will create + :param bool verify: When a session is not given, the client will create a non-authenticated session. This parameter is passed to the session that is created. If set to False, it allows barbicanclient to perform "insecure" TLS (https) requests. The server's certificate will not be verified against any certificate authorities. - WARNING: This option should be used with caution. - :param service_type: Used as an endpoint filter when using an - authenticated keystone session. Defaults to 'key-management'. - :param service_name: Used as an endpoint filter when using an + WARNING: This option should be used with extreme caution. + :param str service_type: Used as an endpoint filter when using an + authenticated keystone session. Defaults to 'key-manager'. + :param str service_name: Used as an endpoint filter when using an authenticated keystone session. - :param interface: Used as an endpoint filter when using an + :param str interface: Used as an endpoint filter when using an authenticated keystone session. Defaults to 'public'. - :param region_name: Used as an endpoint filter when using an + :param str region_name: Used as an endpoint filter when using an authenticated keystone session. """ LOG.debug("Creating Client object") diff --git a/barbicanclient/containers.py b/barbicanclient/containers.py index 38c67712..6fc0b97a 100644 --- a/barbicanclient/containers.py +++ b/barbicanclient/containers.py @@ -68,9 +68,7 @@ class ContainerFormatter(formatter.EntityFormatter): class Container(ContainerFormatter): - """ - Containers are used to keep track of the data stored in Barbican. - """ + """Container is a generic grouping of Secrets""" _entity = 'containers' _type = 'generic' @@ -151,6 +149,7 @@ class Container(ContainerFormatter): @property def secrets(self, cache=True): + """List of Secrets in Containers""" if not self._cached_secrets or not cache: self._fill_secrets_from_secret_refs() return self._cached_secrets @@ -180,6 +179,7 @@ class Container(ContainerFormatter): @_immutable_after_save def store(self): + """Store Container in Barbican""" secret_refs = self._get_secrets_and_store_them_if_necessary() container_dict = base.filter_empty_keys({ @@ -197,6 +197,7 @@ class Container(ContainerFormatter): return self.container_ref def delete(self): + """Delete container from Barbican""" if self._container_ref: self._api._delete(self._container_ref) self._container_ref = None @@ -320,14 +321,17 @@ class RSAContainer(RSAContainerFormatter, Container): @property def public_key(self): + """Secret containing the Public Key""" return self._get_named_secret("public_key") @property def private_key(self): + """Secret containing the Private Key""" return self._get_named_secret("private_key") @property def private_key_passphrase(self): + """Secret containing the Passphrase""" return self._get_named_secret("private_key_passphrase") @public_key.setter @@ -444,18 +448,22 @@ class CertificateContainer(CertificateContainerFormatter, Container): @property def certificate(self): + """Secret containing the certificate""" return self._get_named_secret("certificate") @property def private_key(self): + """Secret containing the private key""" return self._get_named_secret("private_key") @property def private_key_passphrase(self): + """Secret containing the passphrase""" return self._get_named_secret("private_key_passphrase") @property def intermediates(self): + """Secret containing intermediate certificates""" return self._get_named_secret("intermediates") @certificate.setter @@ -491,6 +499,12 @@ class CertificateContainer(CertificateContainerFormatter, Container): class ContainerManager(base.BaseEntityManager): + """ + EntityManager for Container entities + + You should use the ContainerManager exposed by the Client and should not + need to instantiate your own. + """ _container_map = { 'generic': Container, @@ -503,9 +517,9 @@ class ContainerManager(base.BaseEntityManager): def get(self, container_ref): """ - Get a Container + Retrieve an existing Container from Barbican - :param container_ref: Full HATEOAS reference to a Container + :param str container_ref: Full HATEOAS reference to a Container :returns: Container object or a subclass of the appropriate type """ LOG.debug('Getting container - Container href: {0}' @@ -589,11 +603,15 @@ class ContainerManager(base.BaseEntityManager): def create(self, name=None, secrets=None): """ - Create a Container + Factory method for `Container` objects + + `Container` objects returned by this method have not yet been + stored in Barbican. :param name: A friendly name for the Container :param secrets: Secrets to populate when creating a Container :returns: Container + :rtype: :class:`barbicanclient.containers.Container` """ return Container( api=self._api, @@ -604,13 +622,17 @@ class ContainerManager(base.BaseEntityManager): def create_rsa(self, name=None, public_key=None, private_key=None, private_key_passphrase=None): """ - Create an RSAContainer + Factory method for `RSAContainer` objects + + `RSAContainer` objects returned by this method have not yet been + stored in Barbican. :param name: A friendly name for the RSAContainer :param public_key: Secret object containing a Public Key :param private_key: Secret object containing a Private Key :param private_key_passphrase: Secret object containing a passphrase :returns: RSAContainer + :rtype: :class:`barbicanclient.containers.RSAContainer` """ return RSAContainer( api=self._api, @@ -624,7 +646,10 @@ class ContainerManager(base.BaseEntityManager): intermediates=None, private_key=None, private_key_passphrase=None): """ - Create a CertificateContainer + Factory method for `CertificateContainer` objects + + `CertificateContainer` objects returned by this method have not yet + been stored in Barbican. :param name: A friendly name for the CertificateContainer :param certificate: Secret object containing a Certificate @@ -632,6 +657,7 @@ class ContainerManager(base.BaseEntityManager): :param private_key: Secret object containing a Private Key :param private_key_passphrase: Secret object containing a passphrase :returns: CertificateContainer + :rtype: :class:`barbicanclient.containers.CertificateContainer` """ return CertificateContainer( api=self._api, @@ -644,7 +670,7 @@ class ContainerManager(base.BaseEntityManager): def delete(self, container_ref): """ - Delete a Container + Delete a Container from Barbican :param container_ref: Full HATEOAS reference to a Container """ @@ -654,7 +680,8 @@ class ContainerManager(base.BaseEntityManager): def list(self, limit=10, offset=0, name=None, type=None): """ - List all containers for the project + List containers for the project. This method uses the limit and offset + parameters for paging. :param limit: Max number of containers returned :param offset: Offset containers to begin list diff --git a/barbicanclient/orders.py b/barbicanclient/orders.py index e4315e78..b5d01c58 100644 --- a/barbicanclient/orders.py +++ b/barbicanclient/orders.py @@ -187,6 +187,10 @@ class Order(object): @immutable_after_save def submit(self): + """ + Submit the Order to Barbican. New Order objects are not persisted + in Barbican until this method is called. + """ order_dict = {'type': self._type, 'meta': self._meta} LOG.debug("Request body: {0}".format(order_dict)) response = self._api._post(self._entity, order_dict) @@ -195,6 +199,9 @@ class Order(object): return self._order_ref def delete(self): + """ + Deletes the Order from Barbican + """ if self._order_ref: self._api._delete(self._order_ref) self._order_ref = None @@ -203,6 +210,9 @@ class Order(object): class KeyOrder(Order, KeyOrderFormatter): + """ + KeyOrders can be used to request random key material from Barbican + """ _type = 'key' def __init__(self, api, name=None, algorithm=None, bit_length=None, @@ -223,6 +233,11 @@ class KeyOrder(Order, KeyOrderFormatter): @property def mode(self): + """Encryption mode being used with this key + + The mode could be set to "CBC" for example, when requesting a key that + will be used for AES encryption in CBC mode. + """ return self._meta.get('mode') @property @@ -264,6 +279,8 @@ class AsymmetricOrder(Order, AsymmetricOrderFormatter): @property def pass_phrase(self): + """Passphrase to be used for passphrase protected asymmetric keys + """ return self._meta.get('pass_phrase') @pass_phrase.setter @@ -276,6 +293,9 @@ class AsymmetricOrder(Order, AsymmetricOrderFormatter): class OrderManager(base.BaseEntityManager): + """ + Entity Manager for Order entitites + """ _order_type_to_class_map = { 'key': KeyOrder, @@ -287,7 +307,7 @@ class OrderManager(base.BaseEntityManager): def get(self, order_ref): """ - Get an Order + Retrieve an existing Order from Barbican :param order_ref: Full HATEOAS reference to an Order :returns: An instance of the appropriate subtype of Order @@ -318,7 +338,10 @@ class OrderManager(base.BaseEntityManager): def create_key(self, name=None, algorithm=None, bit_length=None, mode=None, payload_content_type=None, expiration=None): """ - Create an Order for a Symmetric Key + Factory method for `KeyOrder` objects + + `KeyOrder` objects returned by this method have not yet been submitted + to the Barbican service. :param name: A friendly name for the secret to be created :param algorithm: The algorithm associated with this secret key @@ -327,6 +350,7 @@ class OrderManager(base.BaseEntityManager): :param payload_content_type: The format/type of the secret data :param expiration: The expiration time of the secret in ISO 8601 format :returns: KeyOrder + :rtype: :class:`barbicanclient.orders.KeyOrder` """ return KeyOrder(api=self._api, name=name, algorithm=algorithm, bit_length=bit_length, mode=mode, @@ -337,7 +361,10 @@ class OrderManager(base.BaseEntityManager): pass_phrase=None, payload_content_type=None, expiration=None): """ - Create an Order for an Asymmetric Key + Factory method for `AsymmetricOrder` objects + + `AsymmetricOrder` objects returned by this method have not yet been + submitted to the Barbican service. :param name: A friendly name for the container to be created :param algorithm: The algorithm associated with this secret key @@ -345,7 +372,8 @@ class OrderManager(base.BaseEntityManager): :param pass_phrase: Optional passphrase :param payload_content_type: The format/type of the secret data :param expiration: The expiration time of the secret in ISO 8601 format - :returns AsymmetricOrder + :returns: AsymmetricOrder + :rtype: :class:`barbicanclient.orders.AsymmetricOrder` """ return AsymmetricOrder(api=self._api, name=name, algorithm=algorithm, bit_length=bit_length, pass_phrase=pass_phrase, @@ -354,7 +382,7 @@ class OrderManager(base.BaseEntityManager): def delete(self, order_ref): """ - Delete an Order + Delete an Order from Barbican :param order_ref: The href for the order """ @@ -364,7 +392,9 @@ class OrderManager(base.BaseEntityManager): def list(self, limit=10, offset=0): """ - List all Orders for the project + List Orders for the project + + This method uses the limit and offset parameters for paging. :param limit: Max number of orders returned :param offset: Offset orders to begin list diff --git a/barbicanclient/secrets.py b/barbicanclient/secrets.py index 30f6fc69..f6f9c58b 100644 --- a/barbicanclient/secrets.py +++ b/barbicanclient/secrets.py @@ -71,7 +71,8 @@ class SecretFormatter(formatter.EntityFormatter): class Secret(SecretFormatter): """ - Secrets are used to keep track of the data stored in Barbican. + Secrets represent keys, credentials, and other sensitive data that is + stored by the Barbican service. """ _entity = 'secrets' @@ -80,6 +81,11 @@ class Secret(SecretFormatter): payload_content_type=None, payload_content_encoding=None, secret_ref=None, created=None, updated=None, content_types=None, status=None): + """ + Secret objects should not be instantiated directly. You should use + the `create` or `get` methods of the + :class:`barbicanclient.secrets.SecretManager` instead. + """ self._api = api self._secret_ref = secret_ref self._fill_from_data( @@ -163,6 +169,9 @@ class Secret(SecretFormatter): @property def payload(self): + """ + Lazy-loaded property that holds the unencrypted data + """ if not self._payload: self._fetch_payload() return self._payload @@ -219,6 +228,10 @@ class Secret(SecretFormatter): @immutable_after_save def store(self): + """ + Stores the Secret in Barbican. New Secret objects are not persisted + in Barbican until this method is called. + """ secret_dict = base.filter_empty_keys({ 'name': self.name, 'payload': self.payload, @@ -239,6 +252,9 @@ class Secret(SecretFormatter): return self.secret_ref def delete(self): + """ + Deletes the Secret from Barbican + """ if self._secret_ref: self._api._delete(self._secret_ref) self._secret_ref = None @@ -306,17 +322,20 @@ class Secret(SecretFormatter): class SecretManager(base.BaseEntityManager): + """Entity Manager for Secret entities""" def __init__(self, api): super(SecretManager, self).__init__(api, 'secrets') def get(self, secret_ref, payload_content_type=None): """ - Get a Secret + Retrieve an existing Secret from Barbican - :param secret_ref: Full HATEOAS reference to a Secret - :param payload_content_type: Content type to use for payload decryption - :returns: Secret + :param str secret_ref: Full HATEOAS reference to a Secret + :param str payload_content_type: Content type to use for payload + decryption + :returns: Secret object retrieved from Barbican + :rtype: :class:`barbicanclient.secrets.Secret` """ LOG.debug("Getting secret - Secret href: {0}".format(secret_ref)) base.validate_ref(secret_ref, 'Secret') @@ -330,7 +349,10 @@ class SecretManager(base.BaseEntityManager): payload_content_type=None, payload_content_encoding=None, algorithm=None, bit_length=None, mode=None, expiration=None): """ - Create a Secret + Factory method for creating new `Secret` objects + + Secrets returned by this method have not yet been stored in the + Barbican service. :param name: A friendly name for the Secret :param payload: The unencrypted secret data @@ -340,7 +362,8 @@ class SecretManager(base.BaseEntityManager): :param bit_length: The bit length of this secret key :param mode: The algorithm mode used with this secret key :param expiration: The expiration time of the secret in ISO 8601 format - :returns: Secret + :returns: A new Secret object + :rtype: :class:`barbicanclient.secrets.Secret` """ return Secret(api=self._api, name=name, payload=payload, payload_content_type=payload_content_type, @@ -350,9 +373,9 @@ class SecretManager(base.BaseEntityManager): def delete(self, secret_ref): """ - Delete a Secret + Delete a Secret from Barbican - :param secret_ref: The href for the secret + :param secret_ref: The href for the secret to be deleted """ if not secret_ref: raise ValueError('secret_ref is required.') @@ -361,7 +384,10 @@ class SecretManager(base.BaseEntityManager): def list(self, limit=10, offset=0, name=None, algorithm=None, mode=None, bits=0): """ - List all Secrets for the project + List Secrets for the project + + This method uses the limit and offset parameters for paging, + and also supports filtering. :param limit: Max number of secrets returned :param offset: Offset secrets to begin list @@ -369,7 +395,9 @@ class SecretManager(base.BaseEntityManager): :param algorithm: Algorithm filter for the list :param mode: Mode filter for the list :param bits: Bits filter for the list - :returns: list of Secret metadata objects + :returns: list of Secret objects that satisfy the provided filter + criteria. + :rtype: list """ LOG.debug('Listing secrets - offset {0} limit {1}'.format(offset, limit)) diff --git a/doc/source/conf.py b/doc/source/conf.py index dbad4458..0cb549ae 100755 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -29,6 +29,7 @@ extensions = [ # autodoc generation is a bit aggressive and a nuisance when doing heavy # text edit cycles. # execute "export SPHINX_DEBUG=1" in your terminal to disable +autoclass_content = 'both' # The suffix of source filenames. source_suffix = '.rst' diff --git a/doc/source/usage.rst b/doc/source/usage.rst index 9ee5b402..7eb0ea5d 100644 --- a/doc/source/usage.rst +++ b/doc/source/usage.rst @@ -88,7 +88,7 @@ Example:: my_order_ref = my_order.submit() -The order reference returned by :meth:`barbicanclient.orders.Order.submit()` +The order reference returned by :meth:`barbicanclient.orders.Order.submit` can later be used to retrieve the order from Barbican. Example::