Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Bundle resolver can use ServiceAccount for auth #7969

Merged
merged 1 commit into from
Jun 11, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
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"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

😻

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