diff --git a/docs/resolver-template/cmd/demoresolver/main.go b/docs/resolver-template/cmd/demoresolver/main.go index 4c11d7164c2..de98984f72e 100644 --- a/docs/resolver-template/cmd/demoresolver/main.go +++ b/docs/resolver-template/cmd/demoresolver/main.go @@ -16,6 +16,8 @@ package main import ( "context" "errors" + "fmt" + "net/url" pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" @@ -51,6 +53,21 @@ func (r *resolver) GetSelector(context.Context) map[string]string { } } +// ValidateResolutionName ensures resolutionName from a request is as expected. +func (r *resolver) ValidateResolutionName(ctx context.Context, resolutionName string) error { + u, err := url.ParseRequestURI(resolutionName) + if err != nil { + return err + } + if u.Scheme != "demoscheme" { + return errors.New(fmt.Sprintf("Invalid Scheme. Want %s, Got %s", "demoscheme", u.Scheme)) + } + if u.Path == "" { + return errors.New("Empty path.") + } + return nil +} + // ValidateParams ensures parameters from a request are as expected. func (r *resolver) ValidateParams(ctx context.Context, params []pipelinev1.Param) error { if len(params) > 0 { @@ -60,7 +77,7 @@ func (r *resolver) ValidateParams(ctx context.Context, params []pipelinev1.Param } // Resolve uses the given params to resolve the requested file or resource. -func (r *resolver) Resolve(ctx context.Context, params []pipelinev1.Param) (framework.ResolvedResource, error) { +func (r *resolver) Resolve(ctx context.Context, resolutionName string, params []pipelinev1.Param) (framework.ResolvedResource, error) { return &myResolvedResource{}, nil } diff --git a/docs/resolver-template/cmd/demoresolver/main_test.go b/docs/resolver-template/cmd/demoresolver/main_test.go index 137aed1b96b..976f0423bcf 100644 --- a/docs/resolver-template/cmd/demoresolver/main_test.go +++ b/docs/resolver-template/cmd/demoresolver/main_test.go @@ -18,6 +18,7 @@ package main import ( "encoding/base64" + "errors" "testing" "time" @@ -27,6 +28,7 @@ import ( frtesting "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework/testing" "github.com/tektoncd/pipeline/test" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + v1 "knative.dev/pkg/apis/duck/v1" _ "knative.dev/pkg/system/testing" ) @@ -48,7 +50,9 @@ func TestResolver(t *testing.T) { resolutioncommon.LabelKeyResolverType: "demo", }, }, - Spec: v1beta1.ResolutionRequestSpec{}, + Spec: v1beta1.ResolutionRequestSpec{ + ResolutionName: "demoscheme://foo/bar", + }, } d := test.Data{ ResolutionRequests: []*v1beta1.ResolutionRequest{request}, @@ -65,3 +69,47 @@ func TestResolver(t *testing.T) { frtesting.RunResolverReconcileTest(ctx, t, d, r, request, expectedStatus, expectedErr) } + +func TestResolver_Failure(t *testing.T) { + ctx, _ := ttesting.SetupFakeContext(t) + + r := &resolver{} + + request := &v1beta1.ResolutionRequest{ + TypeMeta: metav1.TypeMeta{ + APIVersion: "resolution.tekton.dev/v1beta1", + Kind: "ResolutionRequest", + }, + ObjectMeta: metav1.ObjectMeta{ + Name: "rr", + Namespace: "foo", + CreationTimestamp: metav1.Time{Time: time.Now()}, + Labels: map[string]string{ + resolutioncommon.LabelKeyResolverType: "demo", + }, + }, + Spec: v1beta1.ResolutionRequestSpec{ + ResolutionName: "wrongscheme://foo/bar", + }, + } + d := test.Data{ + ResolutionRequests: []*v1beta1.ResolutionRequest{request}, + } + + expectedStatus := &v1beta1.ResolutionRequestStatus{ + Status: v1.Status{ + Conditions: v1.Conditions{ + { + Type: "Succeeded", + Status: "False", + Reason: "ResolutionFailed", + Message: `invalid resource request "foo/rr": Invalid Scheme. Want demoscheme, Got wrongscheme`, + }, + }, + }, + } + + // If you want to test scenarios where an error should occur, pass a non-nil error to RunResolverReconcileTest + expectedErr := errors.New(`invalid resource request "foo/rr": Invalid Scheme. Want demoscheme, Got wrongscheme`) + frtesting.RunResolverReconcileTest(ctx, t, d, r, request, expectedStatus, expectedErr) +} diff --git a/pkg/apis/pipeline/v1/container_validation.go b/pkg/apis/pipeline/v1/container_validation.go index b277f8a73cd..3ae30d8776b 100644 --- a/pkg/apis/pipeline/v1/container_validation.go +++ b/pkg/apis/pipeline/v1/container_validation.go @@ -40,7 +40,7 @@ func (ref *Ref) Validate(ctx context.Context) (errs *apis.FieldError) { errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver", config.BetaAPIFields).ViaField("resolver")) if ref.Name != "" { // make sure that the name is url-like. - if err := nameLikeUrl(ref.Name); err != nil { + if err := refNameLikeUrl(ref.Name); err != nil { errs = errs.Also(apis.ErrInvalidValue(err, "name")) } // cannot have both name and params @@ -61,7 +61,7 @@ func (ref *Ref) Validate(ctx context.Context) (errs *apis.FieldError) { } case ref.Name != "": // ref name can be a Url-like format. - if err := nameLikeUrl(ref.Name); err == nil { + if err := refNameLikeUrl(ref.Name); err == nil { // cannot have both name and params if ref.Params != nil { errs = errs.Also(apis.ErrMultipleOneOf("name", "params")) @@ -84,7 +84,7 @@ func (ref *Ref) Validate(ctx context.Context) (errs *apis.FieldError) { return errs } -func nameLikeUrl(name string) error { +func refNameLikeUrl(name string) error { _, err := url.ParseRequestURI(name) return err } diff --git a/pkg/apis/pipeline/v1/pipelineref_validation.go b/pkg/apis/pipeline/v1/pipelineref_validation.go index fbeab741d14..286117175e1 100644 --- a/pkg/apis/pipeline/v1/pipelineref_validation.go +++ b/pkg/apis/pipeline/v1/pipelineref_validation.go @@ -38,7 +38,7 @@ func (ref *PipelineRef) Validate(ctx context.Context) (errs *apis.FieldError) { errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver", config.BetaAPIFields).ViaField("resolver")) if ref.Name != "" { // make sure that the name is url-like. - if err := nameLikeUrl(ref.Name); err != nil { + if err := refNameLikeUrl(ref.Name); err != nil { errs = errs.Also(apis.ErrInvalidValue(err, "name")) } // cannot have both name and params @@ -59,7 +59,7 @@ func (ref *PipelineRef) Validate(ctx context.Context) (errs *apis.FieldError) { } case ref.Name != "": // Pipelineref name can be a Url-like format. - if err := nameLikeUrl(ref.Name); err == nil { + if err := refNameLikeUrl(ref.Name); err == nil { // cannot have both name and params if ref.Params != nil { errs = errs.Also(apis.ErrMultipleOneOf("name", "params")) diff --git a/pkg/apis/pipeline/v1/taskref_validation.go b/pkg/apis/pipeline/v1/taskref_validation.go index 2d1c5c000c0..12d32068271 100644 --- a/pkg/apis/pipeline/v1/taskref_validation.go +++ b/pkg/apis/pipeline/v1/taskref_validation.go @@ -38,7 +38,7 @@ func (ref *TaskRef) Validate(ctx context.Context) (errs *apis.FieldError) { errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver", config.BetaAPIFields).ViaField("resolver")) if ref.Name != "" { // make sure that the name is url-like. - if err := nameLikeUrl(ref.Name); err != nil { + if err := refNameLikeUrl(ref.Name); err != nil { errs = errs.Also(apis.ErrInvalidValue(err, "name")) } // cannot have both name and params @@ -59,7 +59,7 @@ func (ref *TaskRef) Validate(ctx context.Context) (errs *apis.FieldError) { } case ref.Name != "": // TaskRef name can be a Url-like format. - if err := nameLikeUrl(ref.Name); err == nil { + if err := refNameLikeUrl(ref.Name); err == nil { // cannot have both name and params if ref.Params != nil { errs = errs.Also(apis.ErrMultipleOneOf("name", "params"))