Skip to content

Commit

Permalink
use SSHKey struct to map SSHConfig for the ssh property in build section
Browse files Browse the repository at this point in the history
Signed-off-by: Guillaume Lours <guillaume.lours@docker.com>
  • Loading branch information
glours committed Mar 4, 2022
1 parent d4fbd6f commit 13546f9
Show file tree
Hide file tree
Showing 5 changed files with 74 additions and 23 deletions.
10 changes: 5 additions & 5 deletions loader/full-struct_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ func services(workingDir, homeDir string) []types.ServiceConfig {
Context: "./dir",
Dockerfile: "Dockerfile",
Args: map[string]*string{"foo": strPtr("bar")},
SSH: map[string]string{"default": ""},
SSH: []types.SSHKey{{ID: "default", Path: ""}},
Target: "foo",
Network: "foo",
CacheFrom: []string{"foo", "bar"},
Expand Down Expand Up @@ -571,7 +571,7 @@ services:
args:
foo: bar
ssh:
default: ""
- default
labels:
FOO: BAR
cache_from:
Expand Down Expand Up @@ -1085,9 +1085,9 @@ func fullExampleJSON(workingDir, homeDir string) string {
"args": {
"foo": "bar"
},
"ssh": {
"default": ""
},
"ssh": [
"default"
],
"labels": {
"FOO": "BAR"
},
Expand Down
14 changes: 8 additions & 6 deletions loader/loader.go
Original file line number Diff line number Diff line change
Expand Up @@ -981,17 +981,19 @@ var transformServiceNetworkMap TransformerFunc = func(value interface{}) (interf

var transformSSHConfig TransformerFunc = func(data interface{}) (interface{}, error) {
switch value := data.(type) {
case map[string]interface{}:
return toMapStringString(value, true), nil
case []interface{}:
return transformMappingOrList(value, "=", true)
var result []types.SSHKey
for _, value := range value {
key, val := transformValueToMapEntry(value.(string), "=", false)
result = append(result, types.SSHKey{ID: key, Path: val.(string)})
}
return result, nil
case string:
result := make(map[string]interface{})
if value == "" {
value = "default"
}
key, val := transformValueToMapEntry(value, "=", true)
result[key] = val
key, val := transformValueToMapEntry(value, "=", false)
result := []types.SSHKey{{ID: key, Path: val.(string)}}
return result, nil
}
return nil, errors.Errorf("expected a sting, map or a list, got %T: %#v", data, data)
Expand Down
33 changes: 28 additions & 5 deletions loader/loader_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -1898,13 +1898,30 @@ services:
test:
build:
context: .
ssh: ssh-agent
ssh: default
`)
assert.NilError(t, err)
svc, err := actual.GetService("test")
assert.NilError(t, err)
assert.Assert(t, is.Contains(svc.Build.SSH, "ssh-agent"))
assert.Equal(t, "", svc.Build.SSH["ssh-agent"])
sshValue, err := svc.Build.SSH.Get("default")
assert.NilError(t, err)
assert.Equal(t, "", sshValue)
}

func TestLoadSSHWithKeyValueInBuildConfig(t *testing.T) {
actual, err := loadYAML(`
services:
test:
build:
context: .
ssh: key1=value1
`)
assert.NilError(t, err)
svc, err := actual.GetService("test")
assert.NilError(t, err)
sshValue, err := svc.Build.SSH.Get("key1")
assert.NilError(t, err)
assert.Equal(t, "value1", sshValue)
}

func TestLoadSSHWithKeysValuesInBuildConfig(t *testing.T) {
Expand All @@ -1920,6 +1937,12 @@ services:
assert.NilError(t, err)
svc, err := actual.GetService("test")
assert.NilError(t, err)
assert.Equal(t, "value1", svc.Build.SSH["key1"])
assert.Equal(t, "value2", svc.Build.SSH["key2"])

sshValue, err := svc.Build.SSH.Get("key1")
assert.NilError(t, err)
assert.Equal(t, "value1", sshValue)

sshValue, err = svc.Build.SSH.Get("key2")
assert.NilError(t, err)
assert.Equal(t, "value2", sshValue)
}
8 changes: 2 additions & 6 deletions schema/compose-spec.json
Original file line number Diff line number Diff line change
Expand Up @@ -93,12 +93,8 @@
"args": {"$ref": "#/definitions/list_or_dict"},
"ssh": {
"oneOf": [
{
"type": "string"
},
{
"$ref": "#/definitions/list_or_dict"
}
{"type": "string"},
{"$ref": "#/definitions/list_or_dict"}
]
},
"labels": {"$ref": "#/definitions/list_or_dict"},
Expand Down
32 changes: 31 additions & 1 deletion types/types.go
Original file line number Diff line number Diff line change
Expand Up @@ -427,8 +427,38 @@ func (l Labels) Add(key, value string) Labels {
return l
}

type SSHKey struct {
ID string
Path string
}

// SSHConfig is a mapping type for SSH build config
type SSHConfig map[string]string
type SSHConfig []SSHKey

func (s SSHConfig) Get(id string) (string, error) {
for _, sshKey := range s {
if sshKey.ID == id {
return sshKey.Path, nil
}
}
return "", fmt.Errorf("ID %s not found in SSH keys", id)
}

// MarshalYAML makes SSHKey implement yaml.Marshaller
func (s SSHKey) MarshalYAML() (interface{}, error) {
if s.Path == "" {
return s.ID, nil
}
return fmt.Sprintf("%s: %s", s.ID, s.Path), nil
}

// MarshalJSON makes SSHKey implement json.Marshaller
func (s SSHKey) MarshalJSON() ([]byte, error) {
if s.Path == "" {
return []byte(fmt.Sprintf(`"%s"`, s.ID)), nil
}
return []byte(fmt.Sprintf(`"%s": %s`, s.ID, s.Path)), nil
}

// MappingWithColon is a mapping type that can be converted from a list of
// 'key: value' strings
Expand Down

0 comments on commit 13546f9

Please sign in to comment.