docker / docker/docker-py

Attach Secrets to Existing Service

Open
#2,385 1 comment 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
Python
Stars
7.2k
Forks
1.7k
Avg merge
13d 8h
Merged PRs (30d)
2

Description

Hello, I'm trying to attach a secret to an existing service, which already has a secret in order to achieve zero-downtime secret rotation but the API comes up with an error.

To test:

❯ printf "a123" | docker secret create password-v1 -
01bt1di6vz5dmmwzaj5wph3bt

❯ printf "b123" | docker secret create password-v2 -
ycsb3t2gfcnrn2puzm1hfgg46

❯ docker service create --name nginx --secret password-v1 --replicas 2 --publish 8080:80 nginx
7y28ojb6h8jou7u69516c3lwe
overall progress: 2 out of 2 tasks
1/2: running   [==================================================>]
2/2: running   [==================================================>]
verify: Service converged

❯ docker inspect --format '{{json .Spec.TaskTemplate.ContainerSpec.Secrets}}' nginx | jq .
[
  {
    "File": {
      "Name": "password-v1",
      "UID": "0",
      "GID": "0",
      "Mode": 292
    },
    "SecretID": "01bt1di6vz5dmmwzaj5wph3bt",
    "SecretName": "password-v1"
  }
]

The script I'm using:

#!/usr/bin/env python

import docker

c = docker.APIClient(base_url='unix://var/run/docker.sock')


# define new secret in JSON and service name
# --
# Tried as dictionary too:
# s1 = {'File': {'Name': 'password-v2', 'UID': '0', 'GID': '0', 'Mode': 292}, 'SecretID': 'ycsb3t2gfcnrn2puzm1hfgg46', 'SecretName': 'password-v2'}

s1 = docker.types.SecretReference(secret_id='ycsb3t2gfcnrn2puzm1hfgg46', secret_name='password-v2'),
service_name = 'nginx'

service_inspect = c.inspect_service(service=service_name)
service_id = service_inspect["ID"]
service_version = service_inspect["Version"]["Index"]
containerSpec = c.inspect_service(service=service_name)["Spec"]["TaskTemplate"]["ContainerSpec"]
secrets_spec = c.inspect_service(service=service_name)["Spec"]["TaskTemplate"]["ContainerSpec"]['Secrets']
secrets_spec.append(s1)
containerSpec.update({"Secrets": secrets_spec})
task_tmpl = docker.types.TaskTemplate(containerSpec)
print(task_tmpl)
result = c.update_service(service_id,
                          service_version,
                          fetch_current_spec=True,
                          task_template=task_tmpl)
print(result)

The error I'm getting:

{'ContainerSpec': {'Image': 'nginx:latest@sha256:48cbeee0cb0a3b5e885e36222f969e0a2f41819a68e07aeb6631ca7cb356fed1', 'Init': False, 'DNSConfig': {}, 'Secrets': [{'File': {'Name': 'password-v1', 'UID': '0', 'GID': '0', 'Mode': 292}, 'SecretID': '01bt1di6vz5dmmwzaj5wph3bt', 'SecretName': 'password-v1'}, {'File': {'Name': 'password-v2', 'UID': '0', 'GID': '0', 'Mode': 292}, 'SecretID': 'ycsb3t2gfcnrn2puzm1hfgg46', 'SecretName': 'password-v2'}], 'Isolation': 'default'}}

Traceback (most recent call last):
  File "secrets.py", line 25, in <module>
    task_template=task_tmpl)
  File "/Users/atma/Library/Python/3.7/lib/python/site-packages/docker/utils/decorators.py", line 34, in wrapper
    return f(self, *args, **kwargs)
  File "/Users/atma/Library/Python/3.7/lib/python/site-packages/docker/utils/decorators.py", line 19, in wrapped
    return f(self, resource_id, *args, **kwargs)
  File "/Users/atma/Library/Python/3.7/lib/python/site-packages/docker/api/service.py", line 403, in update_service
    rollback_config
  File "/Users/atma/Library/Python/3.7/lib/python/site-packages/docker/api/service.py", line 93, in _check_api_features
    raise_version_error('ContainerSpec.init', '1.38')
  File "/Users/atma/Library/Python/3.7/lib/python/site-packages/docker/api/service.py", line 11, in raise_version_error
    param, min_version
docker.errors.InvalidVersion: ContainerSpec.init is not supported in API version < 1.38
❯ pip show docker
Name: docker
Version: 4.0.2
Summary: A Python library for the Docker Engine API.
Home-page: https://github.com/docker/docker-py
Author: None
Author-email: None
License: Apache License 2.0
Location: /Users/atma/Library/Python/3.7/lib/python/site-packages
Requires: requests, websocket-client, six
Required-by:

❯ docker info|grep 'Server Version'
Server Version: 18.09.2

Am I doing something wrong?

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start in docker/api/service.py, especially update_service and _check_api_features, then compare the API versions used by docker-py 4.0.2 and Docker Engine 18.09.2. Reproduce the service update from the issue and determine whether attaching the second secret is supported; done means the compatibility behavior or required usage is clearly documented or fixed.

Written by the indexing model from the issue text.

Assessment

Tech stack
docker, python
Domain
devops, infrastructure
Issue type
Bug
Difficulty
3/5
Estimated time
1-2 days
Activity status
Stale
Clarity
Mostly clear
Newbie friendliness
30/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.