Skip to content

Support using swarm Configs as CredentialSpecs in Services. - #1781

Merged
cpuguy83 merged 4 commits into
docker:masterfrom
dperny:swarm-credentialspec
Apr 12, 2019
Merged

Support using swarm Configs as CredentialSpecs in Services.#1781
cpuguy83 merged 4 commits into
docker:masterfrom
dperny:swarm-credentialspec

Conversation

@dperny

@dpernydperny commented Mar 27, 2019

Copy link
Copy Markdown
Contributor

closes#1656

- What I did
Builds on and obsoletes #1656. Uses the final API that went into the engine.

Additionally, in the process, discovered and fixed a bug where the --credential-spec flag would not have been respected on service updates.

- How I did it

When handling configs, add additional logic for handling runtime configs. Additionally, adds logic to replace the config name which the user passes with the config ID, which is what the engine API needs.

- How to verify it

Includes unit tests.

- Description for the changelog

Add ability to use swarm Configs as CredentialSpecs on Services.

@codecov-io

codecov-io commented Mar 28, 2019

Copy link
Copy Markdown

Codecov Report

Merging #1781 into master will increase coverage by 0.4%.
The diff coverage is 91.17%.

@@ Coverage Diff @@## master #1781 +/- ##
=========================================
+ Coverage 56.33% 56.73% +0.4% 
=========================================
Files 308 308 Lines 21504 21610 +106 =========================================
+ Hits 12114 12261 +147 + Misses 8498 8449 -49 - Partials 892 900 +8

@dpernydperny changed the title [WIP] Support using swarm Configs as CredentialSpecs in Services.Support using swarm Configs as CredentialSpecs in Services.Mar 28, 2019
@dperny

Copy link
Copy Markdown
ContributorAuthor

Added tests, removed WIP.

@dperny
dpernyforce-pushed the swarm-credentialspec branch from 007e491 to 23b54b8CompareMarch 28, 2019 19:36
@dperny

Copy link
Copy Markdown
ContributorAuthor

Refactored to reduce cyclomatic complexity, which should hopefully be enough to pass lint.

@dperny

Copy link
Copy Markdown
ContributorAuthor

Added compose support.

Comment threadcli/compose/convert/service.go Outdated
// file in the container. This is used for supporting CredentialSpec
// configs.
if config.Runtime {
if config.Target != "" || config.UID != "" || config.GID != "" || config.Mode != nil {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Wouldn't target and uid/gid still be configurable? (i.e., mount a config as credential-spec, but specify which uid/gid and/or path to use?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No, because a credentialspec is never mounted into the container, or written to the filesystem. And in any case, the actual API type (which is a ConfigReference with a ConfigReferenceRuntimeTarget) does not allow setting file attributes.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🤦‍♂️ ah, yes, makes sense

Comment threadcli/compose/types/types.go Outdated
// the service. Specifically, this currently only indicates that the Config
// is used as a CredentialSpec. If this field is set `true`, then all other
// fields besides `Source` must be empty.
Runtime bool `yaml:",omitempty" json:"runtime,omitempty"`

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we deduct this from the Source value? (IIUC, it will be prefixed with config:// ?)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No. The string config:// should never actually be in the compose code, I think.

We could theoretically determine that a config is a Runtime config by looking for the absence of all other fields, but I usually think it's better to affirmatively determine something rather than make assumptions from the absence.

It would be cleaner to have a whole new type besides FileReferenceConfig but doing so would be more trouble than it's worth, IMHO.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Would it make sense to use a string instead of a bool?
I'd like to avoid a situation where we are adding multiple bools here.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A string representing what? The target, file vs runtime?

@thaJeztahthaJeztahApr 11, 2019

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

One thing to take note is that this type (FileReferenceConfig) is used both for configs and secrets, but we'll only use the "runtime" option for configs; so we might have to create a separate type for configs?

Thinking (UX-wise); in order to use a config as credential-spec, I would have to;

  1. define the Config

    version: "3.8"configs:
    my_credentials_spec:
    file: ./credentials-spec-file.json

    (or, if the config already exists):

    version: "3.8"configs:
    my_credentials_spec:
    external: true
  2. add the Config to the Configs section of the compose file (I guess this can only be with the long syntax, because I'd have to specify the runtime option);

    version: "3.8"services:
    myservice:
    image: myimage:latestconfigs:
    - source: my_credentials_specruntime: trueconfigs:
    my_credentials_spec:
    file: ./credentials-spec-file.json
  3. configure the service to use the config as source for the credentials-spec;

    version: "3.8"services:
    myservice:
    image: myimage:latestcredential_spec:
    config: my_credentials_specconfigs:
    - source: my_credentials_specruntime: trueconfigs:
    my_credentials_spec:
    file: ./my-credential-spec.json

That's a lot of duplication; can we somehow skip step 2. ? i.e., if credential_spec uses config: <some name>, we already know that we want to use a config as source. That config must be defined in the compose-file, but we could attach it automatically to the service (if needed) (or can we do that step even "behind the scenes", daemon-side?)

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Sure, why not.

@andrewhsu

Copy link
Copy Markdown
Contributor

I had a quick look, but I'm not as familiar with this codebase. @cpuguy83 is this patch also something you could have a look at if you have time?

Comment threadcli/command/service/create.go
// all configs in spec.Configs should have both a Name and ID, because
// they come from an already-accepted spec.
for _, config := range spec.Configs {
// if the config is a Runtime target, make sure it's still in use right

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Is this a bug waiting to happen? Is there something we can do now to prevent someone from overlooking this in the future?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

sort of. any future use for runtime specs will probably require similar alterations to the configs logic, which means the implementer will have to look here anyway. then, they'll see this comment, and add the correct removal code.

Comment threadcli/compose/convert/service.go Outdated
File: &file,
ConfigName: obj.Name,
})
// if the obj.File is identical to the zero-value of

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

As above, is this a bug waiting to happen?

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Possibly, but the thing is I'm not sure under what case we'll add another non-file ConfigReference type, so I can't really code defensively against it, and even if I do, it's unlikely that something else will even be implemented at any point.

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Off the top of my head, a value explicitly for runtime targets.

Copy link
Copy Markdown
ContributorAuthor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yes, it would make sense lol

I've made this change, and added tests to boot.

@dperny
dpernyforce-pushed the swarm-credentialspec branch 3 times, most recently from 6bdd646 to 34ebae4CompareApril 11, 2019 18:26
@dperny

Copy link
Copy Markdown
ContributorAuthor

Altered the compose code to infer the need for a Config by the existence of a value in the CredentialSpec.Config field, meaning there is no need to define a Runtime config in the service's configs; merely specifying a CredentialSpec with a Config is sufficient.

This means a service using a CredentialSpec Config would look like this:

version: "3.8"services:
myservice:
image: myimage:latestcredential_spec:
config: my_credentials_specconfigs:
my_credentials_spec:
file: ./my-credential-spec.json|

whereas before this change, it would have looked like this:

version: "3.8"services:
myservice:
image: myimage:latestcredential_spec:
config: my_credentials_specconfigs:
- source: my_credentials_specruntime: trueconfigs:
my_credentials_spec:
file: ./my-credential-spec.json

@dperny
dpernyforce-pushed the swarm-credentialspec branch from 34ebae4 to 074a96cCompareApril 11, 2019 18:46
@thaJeztah

thaJeztah commented Apr 11, 2019

Copy link
Copy Markdown
Member

Thanks! That looks a lot more convenient (and less confusing) 🤗
Also sorry for the long delay between review/comments. Lots of plates to keep spinning 😓

68747470733a2f2f7777772e62616c6f6e64656b6f722e637a2f6173736574732f696d616765732f686c61766e692d6e616269646b612f74616c6972652f74616c6972652e6a70672e6a7067

I'll have another look at the code shortly @cpuguy83@vdemeester if you have some time 🙏

@thaJeztahthaJeztah left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

some comments/questions, but I think it looks pretty sane now

Comment threadcli/compose/schema/schema_test.go
Comment threadcli/command/service/opts.go
// if we're using a swarm Config for the credential spec, over-write it
// here with the config ID
if swarmCredSpec.Config != "" {
for _, config := range refs {

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Was wondering if we should have a resolveConfig / resolveConfigID function somewhere, but (I think) all the lookup loops are just slightly different

@thaJeztahthaJeztah left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

thaJeztahand others added 4 commits April 12, 2019 11:17
Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
Updates the CredentialSpec handling code for services to allow using
swarm Configs.
Additionally, fixes a bug where the `--credential-spec` flag would not
be respected on service updates.
Signed-off-by: Drew Erny <drew.erny@docker.com>
Adds tests for setting and updating swarm service CredentialSpecs,
especially when using a Config as a credential spec.
Signed-off-by: Drew Erny <drew.erny@docker.com>
Signed-off-by: Drew Erny <drew.erny@docker.com>
@dperny
dpernyforce-pushed the swarm-credentialspec branch from 074a96c to 42ec51eCompareApril 12, 2019 16:17

@cpuguy83cpuguy83 left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@cpuguy83
cpuguy83 merged commit 58ec72a into docker:masterApr 12, 2019
@GordonTheTurtleGordonTheTurtle added this to the 19.03.0 milestone Apr 12, 2019
@dperny

Copy link
Copy Markdown
ContributorAuthor

i went and googled "cat in a pope hat" to give this extra powerful blessings

image

Sign up for freeto join this conversation on GitHub. Already have an account? Sign in to comment

Projects

None yet

Development

Successfully merging this pull request may close these issues.

6 participants

@dperny@codecov-io@andrewhsu@thaJeztah@cpuguy83@GordonTheTurtle