From 5395a54b4ed670649525cd9523967355badeac8a Mon Sep 17 00:00:00 2001 From: Drew Erny Date: Thu, 7 Feb 2019 11:59:42 -0600 Subject: [PATCH] Add validation to CredentialSpec configs Adds validation assuring that if a service uses a Config as a CredentialSpec, then the Config is included in the ConfigRefs with a RuntimeTarget. Signed-off-by: Drew Erny --- manager/controlapi/service.go | 29 +++++++++++++++++++++++++++++ manager/controlapi/service_test.go | 15 +++++++++++++++ 2 files changed, 44 insertions(+) diff --git a/manager/controlapi/service.go b/manager/controlapi/service.go index a3ee2c7a4a..8296821beb 100644 --- a/manager/controlapi/service.go +++ b/manager/controlapi/service.go @@ -392,6 +392,21 @@ func validateConfigRefsSpec(spec api.TaskSpec) error { return nil } + // check if we're using a config as a CredentialSpec -- if so, we need to + // verify + var ( + credSpecConfig string + credSpecConfigFound bool + ) + if p := container.Privileges; p != nil { + if cs := p.CredentialSpec; cs != nil { + // if there is no config in the credspec, then this will just be + // assigned to emptystring anyway, so we don't need to check + // existence. + credSpecConfig = cs.GetConfig() + } + } + // Keep a map to track all the targets that will be exposed // The string returned is only used for logging. It could as well be struct{}{} existingTargets := make(map[string]string) @@ -421,6 +436,20 @@ func validateConfigRefsSpec(spec api.TaskSpec) error { existingTargets[fileName] = configRef.ConfigName } + + if configRef.GetRuntime() != nil { + if configRef.ConfigID == credSpecConfig { + credSpecConfigFound = true + } + } + } + + if credSpecConfig != "" && !credSpecConfigFound { + return status.Errorf( + codes.InvalidArgument, + "CredentialSpec references config '%s', but that config isn't in config references with RuntimeTarget", + credSpecConfig, + ) } return nil diff --git a/manager/controlapi/service_test.go b/manager/controlapi/service_test.go index e6b25bdb96..9ad9c75133 100644 --- a/manager/controlapi/service_test.go +++ b/manager/controlapi/service_test.go @@ -788,6 +788,21 @@ func TestConfigValidation(t *testing.T) { ) assert.NoError(t, err) + // test CredentialSpec without ConfigReference + serviceSpec = createSpec("missingruntimetarget", "imagemissingruntimetarget", 1) + serviceSpec.Task.GetContainer().Privileges = &api.Privileges{ + CredentialSpec: &api.Privileges_CredentialSpec{ + Source: &api.Privileges_CredentialSpec_Config{ + Config: configRefCredSpec.ConfigID, + }, + }, + } + _, err = ts.Client.CreateService( + context.Background(), &api.CreateServiceRequest{Spec: serviceSpec}, + ) + t.Logf("error when missing configreference: %v", err) + assert.Error(t, err) + // test config target conflicts on update serviceSpec1 := createServiceSpecWithConfigs("service5", configRef2, configRef3) // Copy this service, but delete the configs for creation