diff options
author | Joffrey F <joffrey@docker.com> | 2017-02-09 19:08:24 -0800 |
---|---|---|
committer | Joffrey F <joffrey@docker.com> | 2017-02-13 17:05:58 -0800 |
commit | 52bae3ca2cf9547d760d0dff8643a2f83133f5ad (patch) | |
tree | 8f84880a009798bb87a71a09f145c7a4189ab094 | |
parent | 35f37a0936ed1ffabad18bac4cdde36518fb3b34 (diff) | |
download | docker-py-52bae3ca2cf9547d760d0dff8643a2f83133f5ad.tar.gz |
Implement secrets API
Signed-off-by: Joffrey F <joffrey@docker.com>
-rw-r--r-- | docker/api/client.py | 2 | ||||
-rw-r--r-- | docker/api/secret.py | 87 | ||||
-rw-r--r-- | docker/client.py | 8 | ||||
-rw-r--r-- | docker/models/secrets.py | 69 |
4 files changed, 166 insertions, 0 deletions
diff --git a/docker/api/client.py b/docker/api/client.py index 0098d44..99d7879 100644 --- a/docker/api/client.py +++ b/docker/api/client.py @@ -15,6 +15,7 @@ from .exec_api import ExecApiMixin from .image import ImageApiMixin from .network import NetworkApiMixin from .plugin import PluginApiMixin +from .secret import SecretApiMixin from .service import ServiceApiMixin from .swarm import SwarmApiMixin from .volume import VolumeApiMixin @@ -48,6 +49,7 @@ class APIClient( ImageApiMixin, NetworkApiMixin, PluginApiMixin, + SecretApiMixin, ServiceApiMixin, SwarmApiMixin, VolumeApiMixin): diff --git a/docker/api/secret.py b/docker/api/secret.py new file mode 100644 index 0000000..4802a4a --- /dev/null +++ b/docker/api/secret.py @@ -0,0 +1,87 @@ +import base64 + +from .. import utils + + +class SecretApiMixin(object): + @utils.minimum_version('1.25') + def create_secret(self, name, data, labels=None): + """ + Create a secret + + Args: + name (string): Name of the secret + data (bytes): Secret data to be stored + labels (dict): A mapping of labels to assign to the secret + + Returns (dict): ID of the newly created secret + """ + if not isinstance(data, bytes): + data = data.encode('utf-8') + + data = base64.b64encode(data) + body = { + 'Data': data, + 'Name': name, + 'Labels': labels + } + + url = self._url('/secrets/create') + return self._result( + self._post_json(url, data=body), True + ) + + @utils.minimum_version('1.25') + @utils.check_resource + def inspect_secret(self, id): + """ + Retrieve secret metadata + + Args: + id (string): Full ID of the secret to remove + + Returns (dict): A dictionary of metadata + + Raises: + :py:class:`docker.errors.NotFound` + if no secret with that ID exists + """ + url = self._url('/secrets/{0}', id) + return self._result(self._get(url), True) + + @utils.minimum_version('1.25') + @utils.check_resource + def remove_secret(self, id): + """ + Remove a secret + + Args: + id (string): Full ID of the secret to remove + + Returns (boolean): True if successful + + Raises: + :py:class:`docker.errors.NotFound` + if no secret with that ID exists + """ + url = self._url('/secrets/{0}', id) + res = self._delete(url) + self._raise_for_status(res) + return True + + @utils.minimum_version('1.25') + def secrets(self, filters=None): + """ + List secrets + + Args: + filters (dict): A map of filters to process on the secrets + list. Available filters: ``names`` + + Returns (list): A list of secrets + """ + url = self._url('/secrets') + params = {} + if filters: + params['filters'] = utils.convert_filters(filters) + return self._result(self._get(url, params=params), True) diff --git a/docker/client.py b/docker/client.py index 127f8dd..09bda67 100644 --- a/docker/client.py +++ b/docker/client.py @@ -4,6 +4,7 @@ from .models.images import ImageCollection from .models.networks import NetworkCollection from .models.nodes import NodeCollection from .models.plugins import PluginCollection +from .models.secrets import SecretCollection from .models.services import ServiceCollection from .models.swarm import Swarm from .models.volumes import VolumeCollection @@ -118,6 +119,13 @@ class DockerClient(object): """ return PluginCollection(client=self) + def secrets(self): + """ + An object for managing secrets on the server. See the + :doc:`secrets documentation <secrets>` for full details. + """ + return SecretCollection(client=self) + @property def services(self): """ diff --git a/docker/models/secrets.py b/docker/models/secrets.py new file mode 100644 index 0000000..ca11ede --- /dev/null +++ b/docker/models/secrets.py @@ -0,0 +1,69 @@ +from ..api import APIClient +from .resource import Model, Collection + + +class Secret(Model): + """A secret.""" + id_attribute = 'ID' + + def __repr__(self): + return "<%s: '%s'>" % (self.__class__.__name__, self.name) + + @property + def name(self): + return self.attrs['Spec']['Name'] + + def remove(self): + """ + Remove this secret. + + Raises: + :py:class:`docker.errors.APIError` + If secret failed to remove. + """ + return self.client.api.remove_secret(self.id) + + +class SecretCollection(Collection): + """Secrets on the Docker server.""" + model = Secret + + def create(self, **kwargs): + obj = self.client.api.create_secret(**kwargs) + return self.prepare_model(obj) + create.__doc__ = APIClient.create_secret.__doc__ + + def get(self, secret_id): + """ + Get a secret. + + Args: + secret_id (str): Secret ID. + + Returns: + (:py:class:`Secret`): The secret. + + Raises: + :py:class:`docker.errors.NotFound` + If the secret does not exist. + :py:class:`docker.errors.APIError` + If the server returns an error. + """ + return self.prepare_model(self.client.api.inspect_secret(secret_id)) + + def list(self, **kwargs): + """ + List secrets. Similar to the ``docker secret ls`` command. + + Args: + filters (dict): Server-side list filtering options. + + Returns: + (list of :py:class:`Secret`): The secrets. + + Raises: + :py:class:`docker.errors.APIError` + If the server returns an error. + """ + resp = self.client.api.secrets(**kwargs) + return [self.prepare_model(obj) for obj in resp] |