Skip to content

Commit

Permalink
Bundle resolver can use ServiceAccount for auth
Browse files Browse the repository at this point in the history
  • Loading branch information
wilstdu authored and tekton-robot committed Jun 11, 2024
1 parent 6ec1a2e commit 08fed74
Show file tree
Hide file tree
Showing 8 changed files with 232 additions and 46 deletions.
2 changes: 1 addition & 1 deletion config/resolvers/200-clusterrole.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -30,5 +30,5 @@ rules:
verbs: ["get", "list"]
# Read-only access to these.
- apiGroups: [""]
resources: ["secrets"]
resources: ["secrets", "serviceaccounts"]
verbs: ["get", "list", "watch"]
2 changes: 2 additions & 0 deletions config/resolvers/bundleresolver-config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,5 +22,7 @@ metadata:
app.kubernetes.io/instance: default
app.kubernetes.io/part-of: tekton-pipelines
data:
# the default service account name to use for bundle requests.
default-service-account: "default"
# The default layer kind in the bundle image.
default-kind: "task"
71 changes: 63 additions & 8 deletions pkg/remoteresolution/resolver/bundle/resolver_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import (
frtesting "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework/testing"
resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common"
bundleresolution "github.com/tektoncd/pipeline/pkg/resolution/resolver/bundle"
"github.com/tektoncd/pipeline/pkg/resolution/resolver/framework"
frameworktesting "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework/testing"
"github.com/tektoncd/pipeline/test"
"github.com/tektoncd/pipeline/test/diff"
Expand Down Expand Up @@ -65,8 +66,12 @@ func TestGetSelector(t *testing.T) {
}
}

func TestValidate(t *testing.T) {
func TestValidateParamsSecret(t *testing.T) {
resolver := bundle.Resolver{}
config := map[string]string{
bundleresolution.ConfigServiceAccount: "default",
}
ctx := framework.InjectResolverConfigToContext(context.Background(), config)

paramsWithTask := []pipelinev1.Param{{
Name: bundleresolution.ParamKind,
Expand All @@ -82,7 +87,7 @@ func TestValidate(t *testing.T) {
Value: *pipelinev1.NewStructuredValues("baz"),
}}
req := v1beta1.ResolutionRequestSpec{Params: paramsWithTask}
if err := resolver.Validate(context.Background(), &req); err != nil {
if err := resolver.Validate(ctx, &req); err != nil {
t.Fatalf("unexpected error validating params: %v", err)
}

Expand All @@ -100,6 +105,50 @@ func TestValidate(t *testing.T) {
Value: *pipelinev1.NewStructuredValues("baz"),
}}
req = v1beta1.ResolutionRequestSpec{Params: paramsWithPipeline}
if err := resolver.Validate(ctx, &req); err != nil {
t.Fatalf("unexpected error validating params: %v", err)
}
}

func TestValidateParamsServiceAccount(t *testing.T) {
resolver := bundle.Resolver{}
config := map[string]string{
bundleresolution.ConfigServiceAccount: "default",
}
ctx := framework.InjectResolverConfigToContext(context.Background(), config)

paramsWithTask := []pipelinev1.Param{{
Name: bundleresolution.ParamKind,
Value: *pipelinev1.NewStructuredValues("task"),
}, {
Name: bundleresolution.ParamName,
Value: *pipelinev1.NewStructuredValues("foo"),
}, {
Name: bundleresolution.ParamBundle,
Value: *pipelinev1.NewStructuredValues("bar"),
}, {
Name: bundleresolution.ParamServiceAccount,
Value: *pipelinev1.NewStructuredValues("baz"),
}}
req := v1beta1.ResolutionRequestSpec{Params: paramsWithTask}
if err := resolver.Validate(ctx, &req); err != nil {
t.Fatalf("unexpected error validating params: %v", err)
}

paramsWithPipeline := []pipelinev1.Param{{
Name: bundleresolution.ParamKind,
Value: *pipelinev1.NewStructuredValues("pipeline"),
}, {
Name: bundleresolution.ParamName,
Value: *pipelinev1.NewStructuredValues("foo"),
}, {
Name: bundleresolution.ParamBundle,
Value: *pipelinev1.NewStructuredValues("bar"),
}, {
Name: bundleresolution.ParamServiceAccount,
Value: *pipelinev1.NewStructuredValues("baz"),
}}
req = v1beta1.ResolutionRequestSpec{Params: paramsWithPipeline}
if err := resolver.Validate(context.Background(), &req); err != nil {
t.Fatalf("unexpected error validating params: %v", err)
}
Expand Down Expand Up @@ -221,7 +270,8 @@ func TestResolve_KeyChainError(t *testing.T) {
Namespace: resolverconfig.ResolversNamespace(system.Namespace()),
},
Data: map[string]string{
bundleresolution.ConfigKind: "task",
bundleresolution.ConfigKind: "task",
bundleresolution.ConfigServiceAccount: "default",
},
}},
}
Expand All @@ -246,10 +296,11 @@ func TestResolve_KeyChainError(t *testing.T) {
}

type params struct {
secret string
bundle string
name string
kind string
serviceAccount string
secret string
bundle string
name string
kind string
}

func TestResolve(t *testing.T) {
Expand Down Expand Up @@ -450,7 +501,8 @@ func TestResolve(t *testing.T) {

resolver := &bundle.Resolver{}
confMap := map[string]string{
bundleresolution.ConfigKind: "task",
bundleresolution.ConfigKind: "task",
bundleresolution.ConfigServiceAccount: "default",
}

for _, tc := range testcases {
Expand Down Expand Up @@ -544,6 +596,9 @@ func createRequest(p *params) *v1beta1.ResolutionRequest {
}, {
Name: bundleresolution.ParamImagePullSecret,
Value: *pipelinev1.NewStructuredValues(p.secret),
}, {
Name: bundleresolution.ParamServiceAccount,
Value: *pipelinev1.NewStructuredValues(p.serviceAccount),
}},
},
}
Expand Down
1 change: 1 addition & 0 deletions pkg/resolution/resolver/bundle/bundle.go
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ const (
// RequestOptions are the options used to request a resource from
// a remote bundle.
type RequestOptions struct {
ServiceAccount string
ImagePullSecret string
Bundle string
EntryName string
Expand Down
3 changes: 3 additions & 0 deletions pkg/resolution/resolver/bundle/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@ package bundle
const (
// ConfigMapName is the bundle resolver's config map
ConfigMapName = "bundleresolver-config"
// ConfigServiceAccount is the configuration field name for controlling
// the Service Account name to use for bundle requests.
ConfigServiceAccount = "default-service-account"
// ConfigKind is the configuration field name for controlling
// what the layer name in the bundle image is.
ConfigKind = "default-kind"
Expand Down
19 changes: 18 additions & 1 deletion pkg/resolution/resolver/bundle/params.go
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,10 @@ import (
"github.com/tektoncd/pipeline/pkg/resolution/resource"
)

// ParamServiceAccount is the parameter defining what service
// account name to use for bundle requests.
const ParamServiceAccount = "serviceAccount"

// ParamImagePullSecret is the parameter defining what secret
// name to use for bundle requests.
const ParamImagePullSecret = "secret"
Expand All @@ -50,6 +54,18 @@ func OptionsFromParams(ctx context.Context, params []pipelinev1.Param) (RequestO
paramsMap[p.Name] = p.Value
}

saVal, ok := paramsMap[ParamServiceAccount]
sa := ""
if !ok || saVal.StringVal == "" {
if saString, ok := conf[ConfigServiceAccount]; ok {
sa = saString
} else {
return opts, errors.New("default Service Account was not set during installation of the bundle resolver")
}
} else {
sa = saVal.StringVal
}

bundleVal, ok := paramsMap[ParamBundle]
if !ok || bundleVal.StringVal == "" {
return opts, fmt.Errorf("parameter %q required", ParamBundle)
Expand All @@ -69,12 +85,13 @@ func OptionsFromParams(ctx context.Context, params []pipelinev1.Param) (RequestO
if kindString, ok := conf[ConfigKind]; ok {
kind = kindString
} else {
return opts, errors.New("default resource Kind was not set during installation of the bundle resolver")
return opts, errors.New("default resource Kind was not set during installation of the bundle resolver")
}
} else {
kind = kindVal.StringVal
}

opts.ServiceAccount = sa
opts.ImagePullSecret = paramsMap[ParamImagePullSecret].StringVal
opts.Bundle = bundleVal.StringVal
opts.EntryName = nameVal.StringVal
Expand Down
8 changes: 3 additions & 5 deletions pkg/resolution/resolver/bundle/resolver.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,7 @@ import (
"time"

"github.com/google/go-containerregistry/pkg/authn/k8schain"
kauth "github.com/google/go-containerregistry/pkg/authn/kubernetes"
resolverconfig "github.com/tektoncd/pipeline/pkg/apis/config/resolver"
pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1"
"github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1"
common "github.com/tektoncd/pipeline/pkg/resolution/common"
Expand Down Expand Up @@ -79,7 +77,7 @@ func (r *Resolver) GetSelector(context.Context) map[string]string {
}

// ValidateParams ensures parameters from a request are as expected.
func (r *Resolver) ValidateParams(ctx context.Context, params []pipelinev1.Param) error {
func (r *Resolver) ValidateParams(ctx context.Context, params []v1.Param) error {
return ValidateParams(ctx, params)
}

Expand All @@ -104,8 +102,8 @@ func ResolveRequest(ctx context.Context, kubeClientSet kubernetes.Interface, req
namespace := common.RequestNamespace(ctx)
kc, err := k8schain.New(ctx, kubeClientSet, k8schain.Options{
Namespace: namespace,
ServiceAccountName: opts.ServiceAccount,
ImagePullSecrets: imagePullSecrets,
ServiceAccountName: kauth.NoServiceAccount,
})
if err != nil {
return nil, err
Expand All @@ -115,7 +113,7 @@ func ResolveRequest(ctx context.Context, kubeClientSet kubernetes.Interface, req
return GetEntry(ctx, kc, opts)
}

func ValidateParams(ctx context.Context, params []pipelinev1.Param) error {
func ValidateParams(ctx context.Context, params []v1.Param) error {
if isDisabled(ctx) {
return errors.New(disabledError)
}
Expand Down
Loading

0 comments on commit 08fed74

Please sign in to comment.