From d238779e34721eca46de3c1bc15631939086207b Mon Sep 17 00:00:00 2001 From: yp05327 <576951401@qq.com> Date: Wed, 14 Feb 2024 14:54:34 +0900 Subject: [PATCH] add inline content for secrets Signed-off-by: yp05327 <576951401@qq.com> --- loader/validate.go | 2 +- loader/validate_test.go | 11 ++++++++ schema/compose-spec.json | 1 + validation/validation.go | 2 +- validation/validation_test.go | 48 ++++++++++++++++++++--------------- 5 files changed, 42 insertions(+), 22 deletions(-) diff --git a/loader/validate.go b/loader/validate.go index 7d77609d..631c2a18 100644 --- a/loader/validate.go +++ b/loader/validate.go @@ -137,7 +137,7 @@ func checkConsistency(project *types.Project) error { if secret.External { continue } - if secret.File == "" && secret.Environment == "" { + if secret.File == "" && secret.Environment == "" && secret.Content == "" { return fmt.Errorf("secret %q must declare either `file` or `environment`: %w", name, errdefs.ErrInvalid) } } diff --git a/loader/validate_test.go b/loader/validate_test.go index baa99775..21cdb3f4 100644 --- a/loader/validate_test.go +++ b/loader/validate_test.go @@ -181,6 +181,17 @@ func TestValidateSecret(t *testing.T) { err := checkConsistency(project) assert.NilError(t, err) }) + t.Run("secret set by inlined content", func(t *testing.T) { + project := &types.Project{ + Secrets: types.Secrets{ + "foo": types.SecretConfig{ + Content: "token=TOKEN", + }, + }, + } + err := checkConsistency(project) + assert.NilError(t, err) + }) t.Run("external secret", func(t *testing.T) { project := &types.Project{ Secrets: types.Secrets{ diff --git a/schema/compose-spec.json b/schema/compose-spec.json index 1b12822d..a4d28f63 100644 --- a/schema/compose-spec.json +++ b/schema/compose-spec.json @@ -721,6 +721,7 @@ "type": "object", "properties": { "name": {"type": "string"}, + "content": {"type": "string"}, "environment": {"type": "string"}, "file": {"type": "string"}, "external": { diff --git a/validation/validation.go b/validation/validation.go index e7cd6754..abf0660c 100644 --- a/validation/validation.go +++ b/validation/validation.go @@ -28,7 +28,7 @@ type checkerFunc func(value any, p tree.Path) error var checks = map[tree.Path]checkerFunc{ "volumes.*": checkVolume, "configs.*": checkFileObject("file", "environment", "content"), - "secrets.*": checkFileObject("file", "environment"), + "secrets.*": checkFileObject("file", "environment", "content"), "services.*.develop.watch.*.path": checkPath, } diff --git a/validation/validation_test.go b/validation/validation_test.go index 6d7e4b2f..4c31cc45 100644 --- a/validation/validation_test.go +++ b/validation/validation_test.go @@ -17,6 +17,7 @@ package validation import ( + "fmt" "testing" "github.com/compose-spec/compose-go/v2/tree" @@ -25,14 +26,14 @@ import ( ) func TestValidateSecret(t *testing.T) { - checker := checks["configs.*"] + treePaths := []tree.Path{"configs.*", "secrets.*"} tests := []struct { name string input string err string }{ { - name: "file config", + name: "file", input: ` name: test file: ./httpd.conf @@ -40,7 +41,7 @@ file: ./httpd.conf err: "", }, { - name: "environment config", + name: "environment", input: ` name: test environment: CONFIG @@ -48,7 +49,7 @@ environment: CONFIG err: "", }, { - name: "inlined config", + name: "inlined", input: ` name: test content: foo=bar @@ -56,23 +57,23 @@ content: foo=bar err: "", }, { - name: "conflict config", + name: "conflict", input: ` name: test environment: CONFIG content: foo=bar `, - err: "configs.test: file|environment|content attributes are mutually exclusive", + err: "%s: file|environment|content attributes are mutually exclusive", }, { - name: "missing config", + name: "missing", input: ` name: test `, - err: "configs.test: one of file|environment|content must be set", + err: "%s: one of file|environment|content must be set", }, { - name: "external config", + name: "external", input: ` name: test external: true @@ -80,17 +81,24 @@ external: true err: "", }, } - for _, tt := range tests { - t.Run(tt.name, func(t *testing.T) { - var input map[string]any - err := yaml.Unmarshal([]byte(tt.input), &input) - assert.NilError(t, err) - err = checker(input, tree.NewPath("configs.test")) - if tt.err == "" { + for _, tp := range treePaths { + checker := checks[tp] + + for _, tt := range tests { + t.Run(fmt.Sprintf("%s %s", tt.name, tp.Parent()), func(t *testing.T) { + var input map[string]any + testTreePath := fmt.Sprintf("%s.test", tp.Parent()) + + err := yaml.Unmarshal([]byte(tt.input), &input) assert.NilError(t, err) - } else { - assert.Equal(t, tt.err, err.Error()) - } - }) + err = checker(input, tree.NewPath(testTreePath)) + if tt.err == "" { + assert.NilError(t, err) + } else { + assert.Equal(t, fmt.Sprintf(tt.err, testTreePath), err.Error()) + } + }) + } } + }