diff --git a/cli/compose/convert/compose.go b/cli/compose/convert/compose.go index 7b369596f969..0d19ae1fdfbf 100644 --- a/cli/compose/convert/compose.go +++ b/cli/compose/convert/compose.go @@ -110,7 +110,13 @@ func Secrets(namespace Namespace, secrets map[string]composetypes.SecretConfig) if err != nil { return nil, err } - result = append(result, swarm.SecretSpec{Annotations: obj.Annotations, Data: obj.Data}) + spec := swarm.SecretSpec{Annotations: obj.Annotations, Data: obj.Data} + if secret.TemplateDriver != "" { + spec.Templating = &swarm.Driver{ + Name: secret.TemplateDriver, + } + } + result = append(result, spec) } return result, nil } @@ -127,7 +133,13 @@ func Configs(namespace Namespace, configs map[string]composetypes.ConfigObjConfi if err != nil { return nil, err } - result = append(result, swarm.ConfigSpec{Annotations: obj.Annotations, Data: obj.Data}) + spec := swarm.ConfigSpec{Annotations: obj.Annotations, Data: obj.Data} + if config.TemplateDriver != "" { + spec.Templating = &swarm.Driver{ + Name: config.TemplateDriver, + } + } + result = append(result, spec) } return result, nil } diff --git a/cli/compose/loader/loader_test.go b/cli/compose/loader/loader_test.go index 7b72ad768c57..6e7bc2c0a4f7 100644 --- a/cli/compose/loader/loader_test.go +++ b/cli/compose/loader/loader_test.go @@ -1463,3 +1463,64 @@ services: }) } } + +func TestLoadTemplateDriver(t *testing.T) { + config, err := loadYAML(` +version: '3.7' +services: + hello-world: + image: redis:alpine + secrets: + - secret + configs: + - config + +configs: + config: + name: config + external: true + template_driver: config-driver + +secrets: + secret: + name: secret + external: true + template_driver: secret-driver +`) + assert.NilError(t, err) + expected := &types.Config{ + Filename: "filename.yml", + Version: "3.7", + Services: types.Services{ + { + Name: "hello-world", + Image: "redis:alpine", + Configs: []types.ServiceConfigObjConfig{ + { + Source: "config", + }, + }, + Secrets: []types.ServiceSecretConfig{ + { + Source: "secret", + }, + }, + }, + }, + Configs: map[string]types.ConfigObjConfig{ + "config": { + Name: "config", + External: types.External{External: true}, + TemplateDriver: "config-driver", + }, + }, + Secrets: map[string]types.SecretConfig{ + "secret": { + Name: "secret", + External: types.External{External: true}, + TemplateDriver: "secret-driver", + }, + }, + } + assert.DeepEqual(t, config, expected, cmpopts.EquateEmpty()) +} diff --git a/cli/compose/schema/bindata.go b/cli/compose/schema/bindata.go index 9ec4891fa36a..719d6e75ac21 100644 --- a/cli/compose/schema/bindata.go +++ b/cli/compose/schema/bindata.go @@ -467,44 +467,45 @@ DoTuq9lAU9Q4O1xV/59X/w8AAP//zRo7vm9CAAA= "/data/config_schema_v3.7.json": { local: "data/config_schema_v3.7.json", - size: 17777, + size: 17871, modtime: 1518458244, compressed: ` -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 +AP//VDCKUc9FAAA= `, }, diff --git a/cli/compose/schema/data/config_schema_v3.7.json b/cli/compose/schema/data/config_schema_v3.7.json index f1597df001e6..46f2d0a04406 100644 --- a/cli/compose/schema/data/config_schema_v3.7.json +++ b/cli/compose/schema/data/config_schema_v3.7.json @@ -532,7 +532,8 @@ "name": {"type": "string"} } }, - "labels": {"$ref": "#/definitions/list_or_dict"} + "labels": {"$ref": "#/definitions/list_or_dict"}, + "template_driver": {"type": "string"} }, "patternProperties": {"^x-": {}}, "additionalProperties": false @@ -550,7 +551,8 @@ "name": {"type": "string"} } }, - "labels": {"$ref": "#/definitions/list_or_dict"} + "labels": {"$ref": "#/definitions/list_or_dict"}, + "template_driver": {"type": "string"} }, "patternProperties": {"^x-": {}}, "additionalProperties": false diff --git a/cli/compose/types/types.go b/cli/compose/types/types.go index 6c1a0dd7583d..fa2bc186b518 100644 --- a/cli/compose/types/types.go +++ b/cli/compose/types/types.go @@ -414,11 +414,12 @@ type CredentialSpecConfig struct { // FileObjectConfig is a config type for a file used by a service type FileObjectConfig struct { - Name string `yaml:",omitempty"` - File string `yaml:",omitempty"` - External External `yaml:",omitempty"` - Labels Labels `yaml:",omitempty"` - Extras map[string]interface{} `yaml:",inline"` + Name string `yaml:",omitempty"` + File string `yaml:",omitempty"` + External External `yaml:",omitempty"` + Labels Labels `yaml:",omitempty"` + Extras map[string]interface{} `yaml:",inline"` + TemplateDriver string `mapstructure:"template_driver" yaml:"template_driver,omitempty"` } // SecretConfig for a secret