diff --git a/docs/cluster-resolver.md b/docs/cluster-resolver.md index 3e0d68eca14..354bd2061dd 100644 --- a/docs/cluster-resolver.md +++ b/docs/cluster-resolver.md @@ -40,7 +40,7 @@ for the name, namespace and defaults that the resolver ships with. | `default-kind` | The default resource kind to fetch if not specified in parameters. | `task`, `pipeline` | | `default-namespace` | The default namespace to fetch resources from if not specified in parameters. | `default`, `some-namespace` | | `allowed-namespaces` | An optional comma-separated list of namespaces which the resolver is allowed to access. Defaults to empty, meaning all namespaces are allowed. | `default,some-namespace`, (empty) | -| `blocked-namespaces` | An optional comma-separated list of namespaces which the resolver is blocked from accessing. Defaults to empty, meaning all namespaces are allowed. | `default,other-namespace`, (empty) | +| `blocked-namespaces` | An optional comma-separated list of namespaces which the resolver is blocked from accessing. If the value is a `*` all namespaces will be disallowed and allowed namespace will need to be explicitely listed in `allowed-namespaces`. Defaults to empty, meaning all namespaces are allowed. | `default,other-namespace`, (empty) | ## Usage diff --git a/pkg/resolution/resolver/cluster/resolver.go b/pkg/resolution/resolver/cluster/resolver.go index b289960d0b6..44c5c800b9e 100644 --- a/pkg/resolution/resolver/cluster/resolver.go +++ b/pkg/resolution/resolver/cluster/resolver.go @@ -279,6 +279,14 @@ func populateParamsWithDefaults(ctx context.Context, origParams []pipelinev1.Par return nil, fmt.Errorf("access to specified namespace %s is blocked", params[NamespaceParam]) } + if conf[AllowedNamespacesKey] != "" && isInCommaSeparatedList(params[NamespaceParam], conf[AllowedNamespacesKey]) { + return params, nil + } + + if conf[BlockedNamespacesKey] != "" && conf[BlockedNamespacesKey] == "*" { + return nil, fmt.Errorf("only explicit allowed access to namespaces is allowed") + } + if conf[AllowedNamespacesKey] != "" && !isInCommaSeparatedList(params[NamespaceParam], conf[AllowedNamespacesKey]) { return nil, fmt.Errorf("access to specified namespace %s is not allowed", params[NamespaceParam]) } diff --git a/pkg/resolution/resolver/cluster/resolver_test.go b/pkg/resolution/resolver/cluster/resolver_test.go index 783a701a01f..bfc6def5ae1 100644 --- a/pkg/resolution/resolver/cluster/resolver_test.go +++ b/pkg/resolution/resolver/cluster/resolver_test.go @@ -110,10 +110,11 @@ func TestValidateParamsNotEnabled(t *testing.T) { func TestValidateParamsFailure(t *testing.T) { testCases := []struct { - name string - params map[string]string - conf map[string]string - expectedErr string + name string + params map[string]string + conf map[string]string + expectedErr string + expectedNoErr bool }{ { name: "missing kind", @@ -122,7 +123,8 @@ func TestValidateParamsFailure(t *testing.T) { cluster.NamespaceParam: "bar", }, expectedErr: "missing required cluster resolver params: kind", - }, { + }, + { name: "invalid kind", params: map[string]string{ cluster.KindParam: "banana", @@ -130,13 +132,15 @@ func TestValidateParamsFailure(t *testing.T) { cluster.NameParam: "bar", }, expectedErr: "unknown or unsupported resource kind 'banana'", - }, { + }, + { name: "missing multiple", params: map[string]string{ cluster.KindParam: "task", }, expectedErr: "missing required cluster resolver params: name, namespace", - }, { + }, + { name: "not in allowed namespaces", params: map[string]string{ cluster.KindParam: "task", @@ -147,7 +151,8 @@ func TestValidateParamsFailure(t *testing.T) { cluster.AllowedNamespacesKey: "abc,def", }, expectedErr: "access to specified namespace foo is not allowed", - }, { + }, + { name: "in blocked namespaces", params: map[string]string{ cluster.KindParam: "task", @@ -159,6 +164,31 @@ func TestValidateParamsFailure(t *testing.T) { }, expectedErr: "access to specified namespace foo is blocked", }, + { + name: "blocked by star", + params: map[string]string{ + cluster.KindParam: "task", + cluster.NamespaceParam: "foo", + cluster.NameParam: "baz", + }, + conf: map[string]string{ + cluster.BlockedNamespacesKey: "*", + }, + expectedErr: "only explicit allowed access to namespace is allowed", + }, + { + name: "blocked by star but allowed explicitly", + params: map[string]string{ + cluster.KindParam: "task", + cluster.NamespaceParam: "foo", + cluster.NameParam: "baz", + }, + conf: map[string]string{ + cluster.BlockedNamespacesKey: "*", + cluster.AllowedNamespacesKey: "foo", + }, + expectedNoErr: true, + }, } for _, tc := range testCases { @@ -178,6 +208,12 @@ func TestValidateParamsFailure(t *testing.T) { }) } err := resolver.ValidateParams(ctx, asParams) + if tc.expectedNoErr { + if err != nil { + t.Fatalf("got unexpected error: %v", err) + } + return + } if err == nil { t.Fatalf("got no error, but expected: %s", tc.expectedErr) }