-
Notifications
You must be signed in to change notification settings - Fork 62
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
Preliminary support for @SUMMONDOCKERARGS #186
Conversation
404 on the tests :) |
a52fa25
to
31f52b1
Compare
8e0f550
to
7cf5a34
Compare
7cf5a34
to
3b6d286
Compare
3b6d286
to
71e4da1
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I left some feedback on the docs updates. You should also include updates to the README with this change, since many people will see the README before they see the website (if they ever do).
I'm curious also how this change can help address some of the recent requests we've received in this project to better support multi-line secrets, in particular #184.
docs/_includes/docker.md
Outdated
1. `summon` is | ||
invoking docker as the child process. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
1. `summon` is | |
invoking docker as the child process. | |
1. `summon` is invoking `docker` as the child process. |
Do you mean the docker
CLI or something else?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Yup the docker CLI. I wonder, would it help to say:
summon
is invoking the docker
CLI as the child process.
docs/_includes/docker.md
Outdated
1. `summon` is | ||
invoking docker as the child process. | ||
2. `@SUMMONDOCKERARGS` is replaced with a combination of `--env` and `--volume` | ||
arguments. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I suspect if this line isn't indented, it's going to display weird when the MD is rendered
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It looks like markdown will assume that a new line is a continuation of the previous in this case, unless broken by an empty newline.
dockerArgs = append(dockerArgs, "--volume", v+":"+v) | ||
} | ||
dockerArgs = append(dockerArgs, "--env", k) | ||
|
||
results <- Result{k, v, nil} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we be zeroing results
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Probably a good idea, I don't know if Summon does any zeroization at all. But I think that piece is out of scope of this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't results
being initialized as an empty channel (line 129 above)? So I think we shouldn't need to zero anything, unless I'm missing something?
internal/command/action.go
Outdated
// 2. summon ... sh -c "docker run @SUMMONDOCKERARGS [...]", also replace substrings | ||
// inside args but the replacement is as a single string. | ||
// | ||
// The code below should support (2). There'll be some ambiguity though... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think we should support replacing substrings. I think lots of users wrap their subcommands with bin/bash -ec '...'
, and it would be better for us to continue to support that syntax. I personally can't think of a use case where someone would benefit from using that syntax over Summon directly calling docker, but it may be easier to ensure all docker subcommands are processed correctly.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, we should include this support. Maybe there's some weird docker-in-docker use case where we're running summon inside a container that requires a bash/sh -c ...
???
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Uncomment, added feature and test case.
internal/command/action_test.go
Outdated
@@ -120,6 +127,121 @@ func TestRunAction(t *testing.T) { | |||
|
|||
So(string(content), ShouldEqual, expectedValue) | |||
}) | |||
|
|||
Convey("Docker options correctly injected", t, func() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
So, from my understanding of how things currently work, we only support the following syntax:
summon docker @SUMMONDOCKERARGS someImage someCommand
That being said, we should also have tests for the following situations:
summon /bin/bash -c "docker @SUMMONDOCKERARGS someImage someCommand"
summon --yaml "VAR: !var some/path" /bin/bash -ec "
docker @SUMMONDOCKERARGS someImage someCommand
echo $VAR
"
Although these may not be actual use cases, we should remove as much ambiguity as we can from possible situations.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should also support the case where someone also uses @SUMMONENVFILE and @SUMMONDOCKEROPTS at the same time
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think it's supported by default. The 2 approaches aren't coupled in any way, and so shouldn't interact in anyway (at least on the Summon side of things).
- @SUMMONENVFILE is just a string that points to an env file containing all the resolved values.
- @SUMMONDOCKEROPTS output the Docker CLI options, which are combinations of
--env
and--volume
, such that the environment variables injected by summon to the child process can become available inside a container created with these options.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
That's understandable, but my concern would be changes we might make in the future surrounding how we parse these keywords prefixed with '@' and how we interact with docker args. I personally think it's safer to have tests in place now that ensure that changes don't have unintended conflicts in the future, and the features have enough overlap that it may be good to have a test, just in case. What do you think @diverdane ?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I thought about this a bit. I think a good way to proceed is to
- Acknowledge that the 2 approaches are actually entirely unrelated, particularly in terms of implementation so their implementations need not be tested in unison.
- Since they both result in modification of the arguments of the child process we can have a simple test that ensures that replacing doesn't get messed up.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm liking it! A few nits, and a question on the path of volume mounted files in containers.
docs/_includes/docker.md
Outdated
arguments. | ||
3. Variable `D` uses the `!file` tag and therefore is the only one that | ||
results in a `--volume` argument. The path to this variable inside the container | ||
is as it is on the host. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm assuming that a temp file is being created for these !file
tagged variables. Will the location of the temp file on the host be host-OS dependent, or are we depending this to always be in /tmp? If it's OS dependent, then the path inside the container will be host-OS dependent, and therefore not 100% predictable.
Maybe we should recommend setting TMPDIR to some path on the host so that we can rely on this path inside the container?
Or maybe there's some Summon config, or something we can add to secrets.yml
to indicate the destination location in the container?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Good point. This might get tricky if for host to container you're going from Windows to Linux or vice-versa. I'm wondering now if I should just altogether disregard the case for files since it adds complication. Having --env
would already be a massive improvement.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we can add some new secrets.yml
syntax to allow users to specify a
destination path for files that Summon creates. This could be similar to what is being proposed in this Issue: #190.
The syntax proposed in Issue #190 is something like this:
summon --yaml 'FOO: !file=<path> contents'
summon --yaml 'FOO: !file=<path> $env/aws/ec2/private_key'
For Issue #190, the <path>
would specify a fixed, local location for Summon to create a file. (I don't think this syntax exists and/or is used for some other purpose.)
For @SUMMONDOCKERARGS, the <path>
could potentially specify the location of the file as volume mounted in the container. So the resulting volume option for Docker could logically be:
--volume <local-temp-file-path>:<path>
I think this would be easy for users to understand.
Maybe this can be added as a followup... along with changes to the secretsyml to add this syntax?
WDYT?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I like the idea of allowing the user to specify the location that Summon creates files. Even though not every platform supports /dev/shm
, the benefit of summon creating files is that it is also responsible for cleaning them up... as much as possible we should retain this for the users in the new features we add.
For now I got rid of the implicit --volume
arguments. We'll let the user do that themselves. Some things to note
- Summon does have a way to configure the tmp directory but it's difficult for the user to predict which one is being used. See https://github.com/cyberark/summon/blob/master/internal/command/temp_factory.go#L29. We try
/dev/shm
then os home directory then os tmp directory. It's not great! - I suppose we should just give the user a way to more explicitly specify this directory, then they can volume mount themselves. However there'd still be an issue of going from say Windows to Linux Containers, and vice versa. I suppose we'll need to look into this more.
internal/command/action.go
Outdated
// 2. summon ... sh -c "docker run @SUMMONDOCKERARGS [...]", also replace substrings | ||
// inside args but the replacement is as a single string. | ||
// | ||
// The code below should support (2). There'll be some ambiguity though... |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I agree, we should include this support. Maybe there's some weird docker-in-docker use case where we're running summon inside a container that requires a bash/sh -c ...
???
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This LGTM, I really like the Docker mocking tests! We should probably figure out how we're going to handle the Docker volume mounts and where the temp files are mapped to inside the container. I think this feature can really be enhanced if we can incorporate new secrets.yml syntax !file=<path>
to allow specification of the target file path. Maybe we can keep this change as is, and as a followup create a new PR to incorporate new syntax? Or skip the volume mounting altogether for now, and add this support later.
Dockerfile.acceptance
Outdated
@@ -5,7 +5,8 @@ RUN apk add --no-cache bash \ | |||
git \ | |||
libffi-dev \ | |||
ruby-bundler \ | |||
ruby-dev | |||
ruby-dev \ | |||
docker-cli |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should be moved up to retain alphabetical listing?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done
docs/_includes/docker.md
Outdated
arguments. | ||
3. Variable `D` uses the `!file` tag and therefore is the only one that | ||
results in a `--volume` argument. The path to this variable inside the container | ||
is as it is on the host. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I wonder if we can add some new secrets.yml
syntax to allow users to specify a
destination path for files that Summon creates. This could be similar to what is being proposed in this Issue: #190.
The syntax proposed in Issue #190 is something like this:
summon --yaml 'FOO: !file=<path> contents'
summon --yaml 'FOO: !file=<path> $env/aws/ec2/private_key'
For Issue #190, the <path>
would specify a fixed, local location for Summon to create a file. (I don't think this syntax exists and/or is used for some other purpose.)
For @SUMMONDOCKERARGS, the <path>
could potentially specify the location of the file as volume mounted in the container. So the resulting volume option for Docker could logically be:
--volume <local-temp-file-path>:<path>
I think this would be easy for users to understand.
Maybe this can be added as a followup... along with changes to the secretsyml to add this syntax?
WDYT?
dockerArgs = append(dockerArgs, "--volume", v+":"+v) | ||
} | ||
dockerArgs = append(dockerArgs, "--env", k) | ||
|
||
results <- Result{k, v, nil} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Isn't results
being initialized as an empty channel (line 129 above)? So I think we shouldn't need to zero anything, unless I'm missing something?
}{} | ||
envvars := map[string]string{} | ||
|
||
// Mock server for handling API calls by `docker run` |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This is some slick docker daemon mocking. I haven't used http mocks in a while, this is a good refresher.
// This is a test case for @SUMMONDOCKERARGS. It exercises Docker CLI pointed to a mock | ||
// server. It asserts on the request payload received on the container creation | ||
// endpoint, the volume mounts and environment variables injected by summon are | ||
// expected to be present. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Super fly by comment, so ignore if this is missing something, but I wouldn't have expected this kind of test here. I would have thought that all we're doing is a pre-process, where the command is updated so that @SUMMONDOCKERARGS
is replaced with the --env A --env B...
start or whatever. Then after that, there is nothing new to test, because you're just running summon with a regular docker command.
Closing this in favour of #199 |
Closes #194
@DOCKEROPTS is imagined to make it easier to lift summon secrets into docker. With usage like this in mind:
Using the!file
tag assumes that the file system where summon creates temporary files can be volume mounted to Docker.If you use the
!file
tag you're on your own for now.What does this PR do?
What ticket does this PR close?
Resolves #[relevant GitHub issues, eg 76]
Checklists
Change log
Test coverage
Documentation
README
s) were updated in this PR, and/or there is a follow-on issue to update docs, or