Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support using swarm Configs as CredentialSpecs in Services. #1781

Merged
merged 4 commits into from
Apr 12, 2019

Conversation

dperny
Copy link
Contributor

@dperny dperny commented Mar 27, 2019

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
Copy link

codecov-io commented Mar 28, 2019

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

@dperny dperny 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
Contributor Author

dperny commented Mar 28, 2019

Added tests, removed WIP.

@dperny
Copy link
Contributor Author

dperny commented Mar 28, 2019

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

@dperny
Copy link
Contributor Author

dperny commented Apr 1, 2019

Added compose support.

// 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
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
Contributor Author

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
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

// 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
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
Contributor Author

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
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
Contributor Author

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?

Copy link
Member

@thaJeztah thaJeztah Apr 11, 2019

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:latest
        configs:
          - source: my_credentials_spec
            runtime: true
    
    configs:
      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:latest
        credential_spec:
          config: my_credentials_spec
        configs:
          - source: my_credentials_spec
            runtime: true
    
    configs:
      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
Contributor Author

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
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?

cli/command/service/create.go Show resolved Hide resolved
// 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
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
Contributor Author

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.

File: &file,
ConfigName: obj.Name,
})
// if the obj.File is identical to the zero-value of
Copy link
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
Contributor Author

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
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
Contributor Author

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 dperny force-pushed the swarm-credentialspec branch 3 times, most recently from 6bdd646 to 34ebae4 Compare April 11, 2019 18:26
@dperny
Copy link
Contributor Author

dperny commented Apr 11, 2019

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:latest
    credential_spec:
      config: my_credentials_spec

configs:
  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:latest
    credential_spec:
      config: my_credentials_spec
    configs:
      - source: my_credentials_spec
        runtime: true

configs:
  my_credentials_spec:
    file: ./my-credential-spec.json

@thaJeztah
Copy link
Member

thaJeztah commented Apr 11, 2019

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 🙏

Copy link
Member

@thaJeztah thaJeztah left a comment

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

cli/compose/schema/schema_test.go Show resolved Hide resolved
cli/command/service/opts.go Show resolved Hide resolved
// 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
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

Copy link
Member

@thaJeztah thaJeztah left a comment

Choose a reason for hiding this comment

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

LGTM

thaJeztah and 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>
Copy link
Collaborator

@cpuguy83 cpuguy83 left a comment

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:master Apr 12, 2019
@GordonTheTurtle GordonTheTurtle added this to the 19.03.0 milestone Apr 12, 2019
@dperny
Copy link
Contributor Author

dperny commented Apr 12, 2019

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

image

Sign up for free to 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