From 8570d504a1d2b8ca98ba1e002d1c96a1436228bc Mon Sep 17 00:00:00 2001 From: Guillaume Lours <705411+glours@users.noreply.github.com> Date: Tue, 1 Nov 2022 22:39:45 +0100 Subject: [PATCH 1/2] check if secrets defined in services are defined Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com> --- loader/validate.go | 6 ++++++ loader/validate_test.go | 45 ++++++++++++++++++++++++++++++++++++++++- 2 files changed, 50 insertions(+), 1 deletion(-) diff --git a/loader/validate.go b/loader/validate.go index 4d635889..2b285e98 100644 --- a/loader/validate.go +++ b/loader/validate.go @@ -70,6 +70,12 @@ func checkConsistency(project *types.Project) error { return errors.Wrap(errdefs.ErrInvalid, fmt.Sprintf("service %q refers to undefined config %s", s.Name, config.Source)) } } + + for _, secret := range s.Secrets { + if _, ok := project.Secrets[secret.Source]; !ok { + return errors.Wrap(errdefs.ErrInvalid, fmt.Sprintf("service %q refers to undefined secret %s", s.Name, secret.Source)) + } + } } for name, secret := range project.Secrets { diff --git a/loader/validate_test.go b/loader/validate_test.go index 58268b2e..577d4076 100644 --- a/loader/validate_test.go +++ b/loader/validate_test.go @@ -174,7 +174,7 @@ func TestValidateSecret(t *testing.T) { err := checkConsistency(project) assert.NilError(t, err) }) - t.Run("uset secret", func(t *testing.T) { + t.Run("unset secret type", func(t *testing.T) { project := &types.Project{ Secrets: types.Secrets{ "foo": types.SecretConfig{}, @@ -183,6 +183,49 @@ func TestValidateSecret(t *testing.T) { err := checkConsistency(project) assert.Error(t, err, "secret \"foo\" must declare either `file` or `environment`: invalid compose project") }) + + t.Run("service secret exist", func(t *testing.T) { + project := &types.Project{ + Secrets: types.Secrets{ + "foo": types.SecretConfig{ + External: types.External{ + External: true, + }, + }, + }, + Services: types.Services([]types.ServiceConfig{ + { + Name: "myservice", + Image: "scratch", + Secrets: []types.ServiceSecretConfig{ + { + Source: "foo", + }, + }, + }, + }), + } + err := checkConsistency(project) + assert.NilError(t, err) + }) + + t.Run("service secret undefined", func(t *testing.T) { + project := &types.Project{ + Services: types.Services([]types.ServiceConfig{ + { + Name: "myservice", + Image: "scratch", + Secrets: []types.ServiceSecretConfig{ + { + Source: "foo", + }, + }, + }, + }), + } + err := checkConsistency(project) + assert.Error(t, err, `service "myservice" refers to undefined secret foo: invalid compose project`) + }) } func TestValidateDependsOn(t *testing.T) { From a9ba9214c2e677828bc158114311b1b69577072e Mon Sep 17 00:00:00 2001 From: Guillaume Lours <705411+glours@users.noreply.github.com> Date: Tue, 1 Nov 2022 22:40:31 +0100 Subject: [PATCH 2/2] check existence of resources to avoid creation of empty one in WithoutUnnecessaryResources function Signed-off-by: Guillaume Lours <705411+glours@users.noreply.github.com> --- types/project.go | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-) diff --git a/types/project.go b/types/project.go index 6b28e863..daa70f8f 100644 --- a/types/project.go +++ b/types/project.go @@ -258,25 +258,33 @@ func (p *Project) WithoutUnnecessaryResources() { networks := Networks{} for k := range requiredNetworks { - networks[k] = p.Networks[k] + if value, ok := p.Networks[k]; ok { + networks[k] = value + } } p.Networks = networks volumes := Volumes{} for k := range requiredVolumes { - volumes[k] = p.Volumes[k] + if value, ok := p.Volumes[k]; ok { + volumes[k] = value + } } p.Volumes = volumes secrets := Secrets{} for k := range requiredSecrets { - secrets[k] = p.Secrets[k] + if value, ok := p.Secrets[k]; ok { + secrets[k] = value + } } p.Secrets = secrets configs := Configs{} for k := range requiredConfigs { - configs[k] = p.Configs[k] + if value, ok := p.Configs[k]; ok { + configs[k] = value + } } p.Configs = configs }