Skip to content

Commit

Permalink
container credentials (nektos#868)
Browse files Browse the repository at this point in the history
* Chore: add a snapshot target

* Update: support credentials for private containers

Resolves: nektos#788

* fix: rework container credentials

Signed-off-by: hackercat <me@hackerc.at>

* fix: check if Credentials are not nil

* fix: return on missing credentials key

Co-authored-by: hackercat <me@hackerc.at>
Co-authored-by: mergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
  • Loading branch information
3 people authored Nov 27, 2021
1 parent e793d03 commit 5bdb9ed
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 11 deletions.
7 changes: 7 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -104,3 +104,10 @@ ifneq ($(shell git status -s),)
endif
git tag -a -m "releasing v$(NEW_VERSION)" v$(NEW_VERSION)
git push origin v$(NEW_VERSION)

.PHONY: snapshot
snapshot:
goreleaser build \
--rm-dist \
--single-target \
--snapshot
19 changes: 10 additions & 9 deletions pkg/model/workflow.go
Original file line number Diff line number Diff line change
Expand Up @@ -295,15 +295,16 @@ func commonKeysMatch(a map[string]interface{}, b map[string]interface{}) bool {

// ContainerSpec is the specification of the container to use for the job
type ContainerSpec struct {
Image string `yaml:"image"`
Env map[string]string `yaml:"env"`
Ports []string `yaml:"ports"`
Volumes []string `yaml:"volumes"`
Options string `yaml:"options"`
Entrypoint string
Args string
Name string
Reuse bool
Image string `yaml:"image"`
Env map[string]string `yaml:"env"`
Ports []string `yaml:"ports"`
Volumes []string `yaml:"volumes"`
Options string `yaml:"options"`
Credentials map[string]string `yaml:"credentials"`
Entrypoint string
Args string
Name string
Reuse bool
}

// Step is the structure of one step in a job
Expand Down
30 changes: 30 additions & 0 deletions pkg/model/workflow_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,6 +99,36 @@ jobs:
assert.Contains(t, workflow.Jobs["test2"].Container().Env["foo"], "bar")
}

func TestReadWorkflow_ObjectContainer(t *testing.T) {
yaml := `
name: local-action-docker-url
jobs:
test:
container:
image: r.example.org/something:latest
credentials:
username: registry-username
password: registry-password
env:
HOME: /home/user
runs-on: ubuntu-latest
steps:
- uses: ./actions/docker-url
`

workflow, err := ReadWorkflow(strings.NewReader(yaml))
assert.NoError(t, err, "read workflow should succeed")
assert.Len(t, workflow.Jobs, 1)

container := workflow.GetJob("test").Container()

assert.Contains(t, container.Image, "r.example.org/something:latest")
assert.Contains(t, container.Env["HOME"], "/home/user")
assert.Contains(t, container.Credentials["username"], "registry-username")
assert.Contains(t, container.Credentials["password"], "registry-password")
}

func TestReadWorkflow_StepsTypes(t *testing.T) {
yaml := `
name: invalid step definition
Expand Down
43 changes: 41 additions & 2 deletions pkg/runner/run_context.go
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,11 @@ func (rc *RunContext) startJobContainer() common.Executor {
return true
})

username, password, err := rc.handleCredentials()
if err != nil {
return fmt.Errorf("failed to handle credentials: %s", err)
}

common.Logger(ctx).Infof("\U0001f680 Start image=%s", image)
name := rc.jobContainerName()

Expand All @@ -169,8 +174,8 @@ func (rc *RunContext) startJobContainer() common.Executor {
Entrypoint: []string{"/usr/bin/tail", "-f", "/dev/null"},
WorkingDir: rc.Config.ContainerWorkdir(),
Image: image,
Username: rc.Config.Secrets["DOCKER_USERNAME"],
Password: rc.Config.Secrets["DOCKER_PASSWORD"],
Username: username,
Password: password,
Name: name,
Env: envList,
Mounts: mounts,
Expand Down Expand Up @@ -836,3 +841,37 @@ func (rc *RunContext) localCheckoutPath() (string, bool) {
}
return "", false
}

func (rc *RunContext) handleCredentials() (username, password string, err error) {
// TODO: remove below 2 lines when we can release act with breaking changes
username = rc.Config.Secrets["DOCKER_USERNAME"]
password = rc.Config.Secrets["DOCKER_PASSWORD"]

container := rc.Run.Job().Container()
if container == nil || container.Credentials == nil {
return
}

if container.Credentials != nil && len(container.Credentials) != 2 {
err = fmt.Errorf("invalid property count for key 'credentials:'")
return
}

ee := rc.NewExpressionEvaluator()
var ok bool
if username, ok = ee.InterpolateWithStringCheck(container.Credentials["username"]); !ok {
err = fmt.Errorf("failed to interpolate container.credentials.username")
return
}
if password, ok = ee.InterpolateWithStringCheck(container.Credentials["password"]); !ok {
err = fmt.Errorf("failed to interpolate container.credentials.password")
return
}

if container.Credentials["username"] == "" || container.Credentials["password"] == "" {
err = fmt.Errorf("container.credentials cannot be empty")
return
}

return username, password, err
}

0 comments on commit 5bdb9ed

Please sign in to comment.