From 8a938fc411183766c54ce739668959d91a5a65ab Mon Sep 17 00:00:00 2001 From: Kewei Yang Date: Fri, 1 Mar 2024 18:06:55 +0800 Subject: [PATCH 01/23] Prior to this PR, the `propagatePipelineNameLabelToPipelineRun` function will continuously set the pipeline name label during each `reconcile` process. This may override the results by the `storePipelineSpecAndMergeMeta` function. This may cause some remote resource names to not be set correctly. This commit, when the pipeline name label has been set, the next `reconcile` will not be reset again. --- pkg/reconciler/pipelinerun/pipelinerun.go | 9 +- .../pipelinerun/pipelinerun_test.go | 127 +++++++++++++++++- 2 files changed, 134 insertions(+), 2 deletions(-) diff --git a/pkg/reconciler/pipelinerun/pipelinerun.go b/pkg/reconciler/pipelinerun/pipelinerun.go index 8756c1282f4..8c0acbe1898 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun.go +++ b/pkg/reconciler/pipelinerun/pipelinerun.go @@ -1308,6 +1308,11 @@ func propagatePipelineNameLabelToPipelineRun(pr *v1.PipelineRun) error { if pr.ObjectMeta.Labels == nil { pr.ObjectMeta.Labels = make(map[string]string) } + + if _, ok := pr.ObjectMeta.Labels[pipeline.PipelineLabelKey]; ok { + return nil + } + switch { case pr.Spec.PipelineRef != nil && pr.Spec.PipelineRef.Name != "": pr.ObjectMeta.Labels[pipeline.PipelineLabelKey] = pr.Spec.PipelineRef.Name @@ -1426,7 +1431,9 @@ func storePipelineSpecAndMergeMeta(ctx context.Context, pr *v1.PipelineRun, ps * // Propagate labels from Pipeline to PipelineRun. PipelineRun labels take precedences over Pipeline. pr.ObjectMeta.Labels = kmap.Union(meta.Labels, pr.ObjectMeta.Labels) - pr.ObjectMeta.Labels[pipeline.PipelineLabelKey] = meta.Name + if len(meta.Name) > 0 { + pr.ObjectMeta.Labels[pipeline.PipelineLabelKey] = meta.Name + } // Propagate annotations from Pipeline to PipelineRun. PipelineRun annotations take precedences over Pipeline. pr.ObjectMeta.Annotations = kmap.Union(kmap.ExcludeKeys(meta.Annotations, tknreconciler.KubectlLastAppliedAnnotationKey), pr.ObjectMeta.Annotations) diff --git a/pkg/reconciler/pipelinerun/pipelinerun_test.go b/pkg/reconciler/pipelinerun/pipelinerun_test.go index 33c7be6f8de..b1f9904ccf3 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun_test.go +++ b/pkg/reconciler/pipelinerun/pipelinerun_test.go @@ -3689,7 +3689,6 @@ metadata: PipelineRunAnnotation: PipelineRunValue labels: PipelineRunLabel: PipelineRunValue - tekton.dev/pipeline: WillNotBeUsed name: test-pipeline-run-with-labels namespace: foo spec: @@ -8485,6 +8484,132 @@ spec: } } +func TestReconcile_RemotePipeline_PipelineNameLabel(t *testing.T) { + names.TestingSeed() + + namespace := "foo" + prName := "test-pipeline-run-success" + trName := "test-pipeline-run-success-unit-test-1" + + prs := []*v1.PipelineRun{parse.MustParseV1PipelineRun(t, ` +metadata: + name: test-pipeline-run-success + namespace: foo +spec: + pipelineRef: + resolver: bar + taskRunTemplate: + serviceAccountName: test-sa + timeout: 1h0m0s +`)} + ps := parse.MustParseV1Pipeline(t, ` +metadata: + name: test-pipeline + namespace: foo +spec: + tasks: + - name: unit-test-1 + taskRef: + resolver: bar +`) + notNamePipeline := parse.MustParseV1Pipeline(t, ` +metadata: + namespace: foo +spec: + tasks: + - name: unit-test-1 + taskRef: + resolver: bar +`) + + remoteTask := parse.MustParseV1Task(t, ` +metadata: + name: unit-test-task + namespace: foo +`) + + pipelineBytes, err := yaml.Marshal(ps) + if err != nil { + t.Fatal("fail to marshal pipeline", err) + } + notNamePipelineBytes, err := yaml.Marshal(notNamePipeline) + if err != nil { + t.Fatal("fail to marshal pipeline", err) + } + + taskBytes, err := yaml.Marshal(remoteTask) + if err != nil { + t.Fatal("fail to marshal task", err) + } + + pipelineReq := getResolvedResolutionRequest(t, "bar", pipelineBytes, "foo", prName) + notNamePipelineReq := getResolvedResolutionRequest(t, "bar", notNamePipelineBytes, "foo", prName) + taskReq := getResolvedResolutionRequest(t, "bar", taskBytes, "foo", trName) + + tcs := []struct { + name string + wantPipelineName string + pipelineReq resolutionv1beta1.ResolutionRequest + taskReq resolutionv1beta1.ResolutionRequest + }{{ + name: "remote pipeline contains name", + // Use the name from the remote pipeline + wantPipelineName: ps.Name, + pipelineReq: pipelineReq, + taskReq: taskReq, + }, { + name: "remote pipeline without name", + wantPipelineName: prs[0].Name, + pipelineReq: notNamePipelineReq, + taskReq: taskReq, + }} + + for _, tc := range tcs { + // Unlike the tests above, we do *not* locally define our pipeline or unit-test task. + d := test.Data{ + PipelineRuns: prs, + ServiceAccounts: []*corev1.ServiceAccount{{ + ObjectMeta: metav1.ObjectMeta{Name: prs[0].Spec.TaskRunTemplate.ServiceAccountName, Namespace: namespace}, + }}, + ConfigMaps: []*corev1.ConfigMap{ + { + ObjectMeta: metav1.ObjectMeta{Name: config.GetFeatureFlagsConfigName(), Namespace: system.Namespace()}, + Data: map[string]string{ + "enable-api-fields": "beta", + }, + }, + }, + ResolutionRequests: []*resolutionv1beta1.ResolutionRequest{&tc.taskReq, &tc.pipelineReq}, + } + + prt := newPipelineRunTest(t, d) + defer prt.Cancel() + + wantEvents := []string{ + "Normal Started", + "Normal Running Tasks Completed: 0", + } + reconciledRun, _ := prt.reconcileRun(namespace, prName, wantEvents, false) + if len(reconciledRun.Labels) == 0 { + t.Errorf("the pipeline label in pr is not set") + } + pName := reconciledRun.Labels[pipeline.PipelineLabelKey] + if reconciledRun.Labels[pipeline.PipelineLabelKey] != tc.wantPipelineName { + t.Errorf("want pipeline name %s, but got %s", tc.wantPipelineName, pName) + } + + // Verify the pipeline name label after the second `reconcile`, to prevent it from being overwritten again. + reconciledRun, _ = prt.reconcileRun(namespace, prName, wantEvents, false) + if len(reconciledRun.Labels) == 0 { + t.Errorf("the pipeline label in pr is not set") + } + pName = reconciledRun.Labels[pipeline.PipelineLabelKey] + if reconciledRun.Labels[pipeline.PipelineLabelKey] != tc.wantPipelineName { + t.Errorf("want pipeline name %s, but got %s", tc.wantPipelineName, pName) + } + } +} + // TestReconcile_OptionalWorkspacesOmitted checks that an optional workspace declared by // a Task and a Pipeline can be omitted by a PipelineRun and the run will still start // successfully without an error. From ea1fa7ad1fdcd6c7ebac47043df0f80ccef60825 Mon Sep 17 00:00:00 2001 From: Chitrang Patel Date: Mon, 8 Apr 2024 09:11:10 -0400 Subject: [PATCH 02/23] Remote Resolution Refactor This PR implements an updated resolver framework with slight updates. This is to avoid backwards incompatibility while implementing [TEP-0154](https://github.com/tektoncd/community/pull/1138). The current framework only works with Params. e.g. The interface has ValidateParams and Resolve which takes in Params. Now that we also need to pass in a `URL`, we need to add new methods and change function signatures which leads to API incompatibility with existing custom resolvers. As a result, when users upgrade to new version of Tekton Pipelines, they will be forced to be compatible with the new format because of the interface changes. This PR tries to make it future proof such that if we add new fields to the ResolutionSpec, it will be handled without the need to break users. --- cmd/resolvers/main.go | 15 +- docs/how-to-write-a-resolver.md | 188 +++- docs/resolver-reference.md | 26 +- docs/resolver-template/README.md | 10 +- docs/resolver-template/cmd/resolver/main.go | 101 ++ .../cmd/resolver/main_test.go | 67 ++ .../resolution}/resolutionrequest.go | 6 +- pkg/reconciler/pipelinerun/controller.go | 2 +- pkg/reconciler/pipelinerun/pipelinerun.go | 2 +- .../pipelinerun/resources/pipelineref.go | 12 +- .../pipelinerun/resources/pipelineref_test.go | 99 +- pkg/reconciler/taskrun/controller.go | 2 +- pkg/reconciler/taskrun/resources/taskref.go | 23 +- .../taskrun/resources/taskref_test.go | 65 +- pkg/reconciler/taskrun/resources/taskspec.go | 2 +- pkg/reconciler/taskrun/taskrun.go | 2 +- pkg/remote/resolution/error.go | 12 +- pkg/remote/resolution/resolver.go | 53 +- pkg/remote/resolution/resolver_test.go | 12 +- pkg/remoteresolution/doc.go | 23 + pkg/remoteresolution/remote/resolution/doc.go | 24 + .../remote/resolution/request.go | 32 + .../remote/resolution/resolver.go | 91 ++ .../remote/resolution/resolver_test.go | 181 ++++ .../resolver/bundle/resolver.go | 78 ++ .../resolver/bundle/resolver_test.go | 610 ++++++++++++ .../resolver/cluster/resolver.go | 87 ++ .../resolver/cluster/resolver_test.go | 507 ++++++++++ pkg/remoteresolution/resolver/doc.go | 25 + .../resolver/framework/controller.go | 124 +++ .../resolver/framework/doc.go | 24 + .../resolver/framework/fakeresolver.go | 73 ++ .../resolver/framework/interface.go | 53 + .../resolver/framework/reconciler.go | 230 +++++ .../resolver/framework/reconciler_test.go | 290 ++++++ .../framework/testing/fakecontroller.go | 171 ++++ pkg/remoteresolution/resolver/git/resolver.go | 145 +++ .../resolver/git/resolver_test.go | 908 ++++++++++++++++++ .../refs/main/pipelines/example-pipeline.yaml | 10 + .../refs/main/tasks/example-task.yaml | 9 + .../other/pipelines/example-pipeline.yaml | 10 + .../resolver/http/resolver.go | 100 ++ .../resolver/http/resolver_test.go | 503 ++++++++++ pkg/remoteresolution/resolver/hub/resolver.go | 78 ++ .../resolver/hub/resolver_test.go | 312 ++++++ pkg/remoteresolution/resource/crd_resource.go | 92 ++ .../resource/crd_resource_test.go | 324 +++++++ pkg/remoteresolution/resource/doc.go | 24 + pkg/remoteresolution/resource/request.go | 83 ++ pkg/remoteresolution/resource/request_test.go | 73 ++ pkg/remoteresolution/resource/resource.go | 37 + pkg/resolution/resolver/bundle/resolver.go | 45 +- .../resolver/bundle/resolver_test.go | 32 +- pkg/resolution/resolver/cluster/resolver.go | 118 ++- .../resolver/cluster/resolver_test.go | 20 +- .../resolver/framework/controller.go | 69 +- .../resolver/framework/fakeresolver.go | 19 +- pkg/resolution/resolver/git/config.go | 16 +- pkg/resolution/resolver/git/params.go | 40 +- pkg/resolution/resolver/git/resolver.go | 351 +++---- pkg/resolution/resolver/git/resolver_test.go | 144 +-- pkg/resolution/resolver/http/config.go | 4 +- pkg/resolution/resolver/http/params.go | 16 +- pkg/resolution/resolver/http/resolver.go | 86 +- pkg/resolution/resolver/http/resolver_test.go | 28 +- pkg/resolution/resolver/hub/resolver.go | 196 ++-- pkg/resolution/resolver/hub/resolver_test.go | 4 +- pkg/resolution/resource/crd_resource.go | 70 +- pkg/resolution/resource/crd_resource_test.go | 23 +- pkg/resolution/resource/name.go | 48 +- pkg/resolution/resource/request.go | 2 - test/remoteresolution/resolution.go | 166 ++++ test/{ => resolution}/resolution.go | 16 +- test/resolvers_test.go | 22 +- 74 files changed, 6784 insertions(+), 781 deletions(-) create mode 100644 docs/resolver-template/cmd/resolver/main.go create mode 100644 docs/resolver-template/cmd/resolver/main_test.go rename pkg/{resolution/resolver/internal => internal/resolution}/resolutionrequest.go (91%) create mode 100644 pkg/remoteresolution/doc.go create mode 100644 pkg/remoteresolution/remote/resolution/doc.go create mode 100644 pkg/remoteresolution/remote/resolution/request.go create mode 100644 pkg/remoteresolution/remote/resolution/resolver.go create mode 100644 pkg/remoteresolution/remote/resolution/resolver_test.go create mode 100644 pkg/remoteresolution/resolver/bundle/resolver.go create mode 100644 pkg/remoteresolution/resolver/bundle/resolver_test.go create mode 100644 pkg/remoteresolution/resolver/cluster/resolver.go create mode 100644 pkg/remoteresolution/resolver/cluster/resolver_test.go create mode 100644 pkg/remoteresolution/resolver/doc.go create mode 100644 pkg/remoteresolution/resolver/framework/controller.go create mode 100644 pkg/remoteresolution/resolver/framework/doc.go create mode 100644 pkg/remoteresolution/resolver/framework/fakeresolver.go create mode 100644 pkg/remoteresolution/resolver/framework/interface.go create mode 100644 pkg/remoteresolution/resolver/framework/reconciler.go create mode 100644 pkg/remoteresolution/resolver/framework/reconciler_test.go create mode 100644 pkg/remoteresolution/resolver/framework/testing/fakecontroller.go create mode 100644 pkg/remoteresolution/resolver/git/resolver.go create mode 100644 pkg/remoteresolution/resolver/git/resolver_test.go create mode 100644 pkg/remoteresolution/resolver/git/testdata/test-org/test-repo/refs/main/pipelines/example-pipeline.yaml create mode 100644 pkg/remoteresolution/resolver/git/testdata/test-org/test-repo/refs/main/tasks/example-task.yaml create mode 100644 pkg/remoteresolution/resolver/git/testdata/test-org/test-repo/refs/other/pipelines/example-pipeline.yaml create mode 100644 pkg/remoteresolution/resolver/http/resolver.go create mode 100644 pkg/remoteresolution/resolver/http/resolver_test.go create mode 100644 pkg/remoteresolution/resolver/hub/resolver.go create mode 100644 pkg/remoteresolution/resolver/hub/resolver_test.go create mode 100644 pkg/remoteresolution/resource/crd_resource.go create mode 100644 pkg/remoteresolution/resource/crd_resource_test.go create mode 100644 pkg/remoteresolution/resource/doc.go create mode 100644 pkg/remoteresolution/resource/request.go create mode 100644 pkg/remoteresolution/resource/request_test.go create mode 100644 pkg/remoteresolution/resource/resource.go create mode 100644 test/remoteresolution/resolution.go rename test/{ => resolution}/resolution.go (91%) diff --git a/cmd/resolvers/main.go b/cmd/resolvers/main.go index f66e9cd0a89..0b4eb1aa89f 100644 --- a/cmd/resolvers/main.go +++ b/cmd/resolvers/main.go @@ -21,12 +21,13 @@ import ( "strings" "github.com/tektoncd/pipeline/pkg/apis/resolution/v1alpha1" - "github.com/tektoncd/pipeline/pkg/resolution/resolver/bundle" - "github.com/tektoncd/pipeline/pkg/resolution/resolver/cluster" - "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" - "github.com/tektoncd/pipeline/pkg/resolution/resolver/git" - "github.com/tektoncd/pipeline/pkg/resolution/resolver/http" - "github.com/tektoncd/pipeline/pkg/resolution/resolver/hub" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/bundle" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/cluster" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/git" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/http" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/hub" + hubresolution "github.com/tektoncd/pipeline/pkg/resolution/resolver/hub" filteredinformerfactory "knative.dev/pkg/client/injection/kube/informers/factory/filtered" "knative.dev/pkg/injection/sharedmain" "knative.dev/pkg/signals" @@ -35,7 +36,7 @@ import ( func main() { ctx := filteredinformerfactory.WithSelectors(signals.NewContext(), v1alpha1.ManagedByLabelKey) tektonHubURL := buildHubURL(os.Getenv("TEKTON_HUB_API"), "") - artifactHubURL := buildHubURL(os.Getenv("ARTIFACT_HUB_API"), hub.DefaultArtifactHubURL) + artifactHubURL := buildHubURL(os.Getenv("ARTIFACT_HUB_API"), hubresolution.DefaultArtifactHubURL) sharedmain.MainWithContext(ctx, "controller", framework.NewController(ctx, &git.Resolver{}), diff --git a/docs/how-to-write-a-resolver.md b/docs/how-to-write-a-resolver.md index 0237fa11daf..efa9ee61654 100644 --- a/docs/how-to-write-a-resolver.md +++ b/docs/how-to-write-a-resolver.md @@ -97,6 +97,29 @@ a little bit of boilerplate. Create `cmd/demoresolver/main.go` with the following setup code: +{{% tabs %}} + +{{% tab "Latest Framework" %}} +```go +package main + +import ( + "context" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" + "knative.dev/pkg/injection/sharedmain" +) + +func main() { + sharedmain.Main("controller", + framework.NewController(context.Background(), &resolver{}), + ) +} + +type resolver struct {} +``` +{{% /tab %}} + +{{% tab "Previous Framework" %}} ```go package main @@ -115,6 +138,10 @@ func main() { type resolver struct {} ``` +{{% /tab %}} + +{{% /tabs %}} + This won't compile yet but you can download the dependencies by running: ```bash @@ -189,6 +216,24 @@ example resolver. We'll also need to add another import for this package at the top: +{{% tabs %}} + +{{% tab "Latest Framework" %}} +```go +import ( + "context" + + // Add this one; it defines LabelKeyResolverType we use in GetSelector + "github.com/tektoncd/pipeline/pkg/resolution/common" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" + "knative.dev/pkg/injection/sharedmain" + pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" +) +``` +{{% /tab %}} + +{{% tab "Previous Framework" %}} + ```go import ( "context" @@ -201,21 +246,48 @@ import ( ) ``` -## The `ValidateParams` method +{{% /tab %}} + +{{% /tabs %}} + +## The `Validate` method -The `ValidateParams` method checks that the params submitted as part of +The `Validate` method checks that the resolution-spec submitted as part of a resolution request are valid. Our example resolver doesn't expect -any params so we'll simply ensure that the given map is empty. +any params in the spec so we'll simply ensure that the there are no params. +In the previous version, this was instead called `ValidateParams` method. See below +for the differences. + +{{% tabs %}} + +{{% tab "Latest Framework" %}} ```go -// ValidateParams ensures parameters from a request are as expected. -func (r *resolver) ValidateParams(ctx context.Context, params map[string]string) error { - if len(params) > 0 { +// Validate ensures that the resolution spec from a request is as expected. +func (r *resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestSpec) error { + if len(req.Params) > 0 { return errors.New("no params allowed") } return nil } ``` +{{% /tab %}} + +{{% tab "Previous Framework" %}} + +```go +// ValidateParams ensures that the params from a request are as expected. +func (r *resolver) ValidateParams(ctx context.Context, params []pipelinev1.Param) error { + if len(req.Params) > 0 { + return errors.New("no params allowed") + } + return nil +} +``` + +{{% /tab %}} + +{{% /tabs %}} You'll also need to add the `"errors"` package to your list of imports at the top of the file. @@ -228,13 +300,113 @@ going to return a hard-coded string of YAML. Since Tekton Pipelines currently only supports fetching Pipeline resources via remote resolution that's what we'll return. + The method signature we're implementing here has a `framework.ResolvedResource` interface as one of its return values. This is another type we have to implement but it has a small footprint: +{{% tabs %}} + +{{% tab "Latest Framework" %}} + + +```go +// Resolve uses the given resolution spec to resolve the requested file or resource. +func (r *resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (framework.ResolvedResource, error) { + return &myResolvedResource{}, nil +} + +// our hard-coded resolved file to return +const pipeline = ` +apiVersion: tekton.dev/v1beta1 +kind: Pipeline +metadata: + name: my-pipeline +spec: + tasks: + - name: hello-world + taskSpec: + steps: + - image: alpine:3.15.1 + script: | + echo "hello world" +` + +// myResolvedResource wraps the data we want to return to Pipelines +type myResolvedResource struct {} + +// Data returns the bytes of our hard-coded Pipeline +func (*myResolvedResource) Data() []byte { + return []byte(pipeline) +} + +// Annotations returns any metadata needed alongside the data. None atm. +func (*myResolvedResource) Annotations() map[string]string { + return nil +} + +// RefSource is the source reference of the remote data that records where the remote +// file came from including the url, digest and the entrypoint. None atm. +func (*myResolvedResource) RefSource() *pipelinev1.RefSource { + return nil +} +``` + +{{% /tab %}} + +{{% tab "Previous Framework" %}} + + +```go +// Resolve uses the given resolution spec to resolve the requested file or resource. +func (r *resolver) Resolve(ctx context.Context, params []pipelinev1.Param) (framework.ResolvedResource, error) { + return &myResolvedResource{}, nil +} + +// our hard-coded resolved file to return +const pipeline = ` +apiVersion: tekton.dev/v1beta1 +kind: Pipeline +metadata: + name: my-pipeline +spec: + tasks: + - name: hello-world + taskSpec: + steps: + - image: alpine:3.15.1 + script: | + echo "hello world" +` + +// myResolvedResource wraps the data we want to return to Pipelines +type myResolvedResource struct {} + +// Data returns the bytes of our hard-coded Pipeline +func (*myResolvedResource) Data() []byte { + return []byte(pipeline) +} + +// Annotations returns any metadata needed alongside the data. None atm. +func (*myResolvedResource) Annotations() map[string]string { + return nil +} + +// RefSource is the source reference of the remote data that records where the remote +// file came from including the url, digest and the entrypoint. None atm. +func (*myResolvedResource) RefSource() *pipelinev1.RefSource { + return nil +} +``` + + +{{% /tab %}} + +{{% /tabs %}} + ```go -// Resolve uses the given params to resolve the requested file or resource. -func (r *resolver) Resolve(ctx context.Context, params map[string]string) (framework.ResolvedResource, error) { +// Resolve uses the given resolution spec to resolve the requested file or resource. +func (r *resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (framework.ResolvedResource, error) { return &myResolvedResource{}, nil } diff --git a/docs/resolver-reference.md b/docs/resolver-reference.md index 68fa6fc9273..f2d62e22cf0 100644 --- a/docs/resolver-reference.md +++ b/docs/resolver-reference.md @@ -21,13 +21,33 @@ a resolver](./how-to-write-a-resolver.md). Implementing this interface is required. It provides just enough configuration for the framework to get a resolver running. +{{% tabs %}} + +{{% tab "Upgraded Framework" %}} + +| Method to Implement | Description | +|----------------------|-------------| +| Initialize | Use this method to perform any setup required before the resolver starts receiving requests. | +| GetName | Use this method to return a name to refer to your Resolver by. e.g. `"Git"` | +| GetSelector | Use this method to specify the labels that a resolution request must have to be routed to your resolver. | +| Validate | Use this method to validate the resolution Spec given to your resolver. | +| Resolve | Use this method to perform get the resource based on the ResolutionRequestSpec as input and return it, along with any metadata about it in annotations | + +{{% /tab %}} + +{{% tab "Previous Framework" %}} + | Method to Implement | Description | |----------------------|-------------| | Initialize | Use this method to perform any setup required before the resolver starts receiving requests. | | GetName | Use this method to return a name to refer to your Resolver by. e.g. `"Git"` | | GetSelector | Use this method to specify the labels that a resolution request must have to be routed to your resolver. | -| ValidateParams | Use this method to validate the parameters given to your resolver. | -| Resolve | Use this method to perform get the resource and return it, along with any metadata about it in annotations | +| ValidateParams | Use this method to validate the params given to your resolver. | +| Resolve | Use this method to perform get the resource based on params as input and return it, along with any metadata about it in annotations | + +{{% /tab %}} + +{{% /tabs %}} ## The `ConfigWatcher` Interface @@ -38,7 +58,7 @@ api endpoints or base urls, service account names to use, etc... | Method to Implement | Description | |---------------------|-------------| -| GetConfigName | Use this method to return the name of the configmap admins will use to configure this resolver. Once this interface is implemented your `ValidateParams` and `Resolve` methods will be able to access your latest resolver configuration by calling `framework.GetResolverConfigFromContext(ctx)`. Note that this configmap must exist when your resolver starts - put a default one in your resolver's `config/` directory. | +| GetConfigName | Use this method to return the name of the configmap admins will use to configure this resolver. Once this interface is implemented your `Validate` and `Resolve` methods will be able to access your latest resolver configuration by calling `framework.GetResolverConfigFromContext(ctx)`. Note that this configmap must exist when your resolver starts - put a default one in your resolver's `config/` directory. | ## The `TimedResolution` Interface diff --git a/docs/resolver-template/README.md b/docs/resolver-template/README.md index fbd6a8b5355..829f9845fa1 100644 --- a/docs/resolver-template/README.md +++ b/docs/resolver-template/README.md @@ -19,11 +19,19 @@ You can use this as a template to quickly get a new Resolver up and running with your own preferred storage backend. To reuse the template, simply copy this entire subdirectory to a new -directory. The entire program is defined in +directory. + +The entire program for the `latest` framework is defined in +[`./cmd/resolver/main.go`](./cmd/resolver/main.go) and provides stub +implementations of all the methods defined by the [`framework.Resolver` +interface](../../pkg/remoteresolution/resolver/framework/interface.go). + +If you choose to use the previous framework (soon to be deprecated) is defined in [`./cmd/demoresolver/main.go`](./cmd/demoresolver/main.go) and provides stub implementations of all the methods defined by the [`framework.Resolver` interface](../../pkg/resolution/resolver/framework/interface.go). + Once copied you'll need to run `go mod init` and `go mod tidy` at the root of your project. We don't need this in `tektoncd/resolution` because this submodule relies on the `go.mod` and `go.sum` defined at the root of the repo. diff --git a/docs/resolver-template/cmd/resolver/main.go b/docs/resolver-template/cmd/resolver/main.go new file mode 100644 index 00000000000..8bbb01f958c --- /dev/null +++ b/docs/resolver-template/cmd/resolver/main.go @@ -0,0 +1,101 @@ +/* +Copyright 2024 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package main + +import ( + "context" + "errors" + + pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" + "github.com/tektoncd/pipeline/pkg/resolution/common" + frameworkV1 "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" + filteredinformerfactory "knative.dev/pkg/client/injection/kube/informers/factory/filtered" + "knative.dev/pkg/injection/sharedmain" +) + +func main() { + ctx := filteredinformerfactory.WithSelectors(context.Background(), v1beta1.ManagedByLabelKey) + sharedmain.MainWithContext(ctx, "controller", + framework.NewController(ctx, &resolver{}), + ) +} + +type resolver struct{} + +// Initialize sets up any dependencies needed by the resolver. None atm. +func (r *resolver) Initialize(context.Context) error { + return nil +} + +// GetName returns a string name to refer to this resolver by. +func (r *resolver) GetName(context.Context) string { + return "Demo" +} + +// GetSelector returns a map of labels to match requests to this resolver. +func (r *resolver) GetSelector(context.Context) map[string]string { + return map[string]string{ + common.LabelKeyResolverType: "demo", + } +} + +// Validate ensures resolution spec from a request is as expected. +func (r *resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestSpec) error { + if len(req.Params) > 0 { + return errors.New("no params allowed") + } + return nil +} + +// Resolve uses the given resolution spec to resolve the requested file or resource. +func (r *resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (frameworkV1.ResolvedResource, error) { + return &myResolvedResource{}, nil +} + +// our hard-coded resolved file to return +const pipeline = ` +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: my-pipeline +spec: + tasks: + - name: hello-world + taskSpec: + steps: + - image: alpine:3.15.1 + script: | + echo "hello world" +` + +// myResolvedResource wraps the data we want to return to Pipelines +type myResolvedResource struct{} + +// Data returns the bytes of our hard-coded Pipeline +func (*myResolvedResource) Data() []byte { + return []byte(pipeline) +} + +// Annotations returns any metadata needed alongside the data. None atm. +func (*myResolvedResource) Annotations() map[string]string { + return nil +} + +// RefSource is the source reference of the remote data that records where the remote +// file came from including the url, digest and the entrypoint. None atm. +func (*myResolvedResource) RefSource() *pipelinev1.RefSource { + return nil +} diff --git a/docs/resolver-template/cmd/resolver/main_test.go b/docs/resolver-template/cmd/resolver/main_test.go new file mode 100644 index 00000000000..23b9dcf610b --- /dev/null +++ b/docs/resolver-template/cmd/resolver/main_test.go @@ -0,0 +1,67 @@ +/* + Copyright 2024 The Tekton Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package main + +import ( + "encoding/base64" + "testing" + "time" + + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" + frtesting "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework/testing" + resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + "github.com/tektoncd/pipeline/test" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + _ "knative.dev/pkg/system/testing" +) + +func TestResolver(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{}, + } + d := test.Data{ + ResolutionRequests: []*v1beta1.ResolutionRequest{request}, + } + + expectedStatus := &v1beta1.ResolutionRequestStatus{ + ResolutionRequestStatusFields: v1beta1.ResolutionRequestStatusFields{ + Data: base64.StdEncoding.Strict().EncodeToString([]byte(pipeline)), + }, + } + + // If you want to test scenarios where an error should occur, pass a non-nil error to RunResolverReconcileTest + var expectedErr error + + frtesting.RunResolverReconcileTest(ctx, t, d, r, request, expectedStatus, expectedErr) +} diff --git a/pkg/resolution/resolver/internal/resolutionrequest.go b/pkg/internal/resolution/resolutionrequest.go similarity index 91% rename from pkg/resolution/resolver/internal/resolutionrequest.go rename to pkg/internal/resolution/resolutionrequest.go index be7f78f9a89..a7cf0909ae0 100644 --- a/pkg/resolution/resolver/internal/resolutionrequest.go +++ b/pkg/internal/resolution/resolutionrequest.go @@ -14,13 +14,13 @@ limitations under the License. */ -package internal +package resolution import ( "encoding/base64" "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" - resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + common "github.com/tektoncd/pipeline/pkg/resolution/common" corev1 "k8s.io/api/core/v1" "knative.dev/pkg/apis" duckv1 "knative.dev/pkg/apis/duck/v1" @@ -43,7 +43,7 @@ func CreateResolutionRequestFailureStatus() *v1beta1.ResolutionRequestStatus { Conditions: duckv1.Conditions{{ Type: apis.ConditionSucceeded, Status: corev1.ConditionFalse, - Reason: resolutioncommon.ReasonResolutionFailed, + Reason: common.ReasonResolutionFailed, }}, }, } diff --git a/pkg/reconciler/pipelinerun/controller.go b/pkg/reconciler/pipelinerun/controller.go index 5df3f698548..728cd752882 100644 --- a/pkg/reconciler/pipelinerun/controller.go +++ b/pkg/reconciler/pipelinerun/controller.go @@ -33,7 +33,7 @@ import ( "github.com/tektoncd/pipeline/pkg/pipelinerunmetrics" cloudeventclient "github.com/tektoncd/pipeline/pkg/reconciler/events/cloudevent" "github.com/tektoncd/pipeline/pkg/reconciler/volumeclaim" - resolution "github.com/tektoncd/pipeline/pkg/resolution/resource" + resolution "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" "github.com/tektoncd/pipeline/pkg/tracing" "k8s.io/client-go/tools/cache" "k8s.io/utils/clock" diff --git a/pkg/reconciler/pipelinerun/pipelinerun.go b/pkg/reconciler/pipelinerun/pipelinerun.go index 8c0acbe1898..2b4d8778dde 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun.go +++ b/pkg/reconciler/pipelinerun/pipelinerun.go @@ -52,7 +52,7 @@ import ( tresources "github.com/tektoncd/pipeline/pkg/reconciler/taskrun/resources" "github.com/tektoncd/pipeline/pkg/reconciler/volumeclaim" "github.com/tektoncd/pipeline/pkg/remote" - resolution "github.com/tektoncd/pipeline/pkg/resolution/resource" + resolution "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" "github.com/tektoncd/pipeline/pkg/substitution" "github.com/tektoncd/pipeline/pkg/trustedresources" "github.com/tektoncd/pipeline/pkg/workspace" diff --git a/pkg/reconciler/pipelinerun/resources/pipelineref.go b/pkg/reconciler/pipelinerun/resources/pipelineref.go index 71fd76669dd..226ca35c201 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelineref.go +++ b/pkg/reconciler/pipelinerun/resources/pipelineref.go @@ -24,12 +24,13 @@ import ( v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + resolutionV1beta1 "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" clientset "github.com/tektoncd/pipeline/pkg/client/clientset/versioned" "github.com/tektoncd/pipeline/pkg/reconciler/apiserver" rprp "github.com/tektoncd/pipeline/pkg/reconciler/pipelinerun/pipelinespec" "github.com/tektoncd/pipeline/pkg/remote" - "github.com/tektoncd/pipeline/pkg/remote/resolution" - remoteresource "github.com/tektoncd/pipeline/pkg/resolution/resource" + "github.com/tektoncd/pipeline/pkg/remoteresolution/remote/resolution" + remoteresource "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" "github.com/tektoncd/pipeline/pkg/trustedresources" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -70,7 +71,12 @@ func GetPipelineFunc(ctx context.Context, k8s kubernetes.Interface, tekton clien } replacedParams := pr.Params.ReplaceVariables(stringReplacements, arrayReplacements, objectReplacements) - resolver := resolution.NewResolver(requester, pipelineRun, string(pr.Resolver), "", "", replacedParams) + resolverPayload := remoteresource.ResolverPayload{ + ResolutionSpec: &resolutionV1beta1.ResolutionRequestSpec{ + Params: replacedParams, + }, + } + resolver := resolution.NewResolver(requester, pipelineRun, string(pr.Resolver), resolverPayload) return resolvePipeline(ctx, resolver, name, namespace, k8s, tekton, verificationPolicies) } default: diff --git a/pkg/reconciler/pipelinerun/resources/pipelineref_test.go b/pkg/reconciler/pipelinerun/resources/pipelineref_test.go index 9b173bc49dc..1f94e784bd3 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelineref_test.go +++ b/pkg/reconciler/pipelinerun/resources/pipelineref_test.go @@ -34,15 +34,18 @@ import ( v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + resolutionV1beta1 "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" "github.com/tektoncd/pipeline/pkg/client/clientset/versioned/fake" clientset "github.com/tektoncd/pipeline/pkg/client/clientset/versioned/fake" "github.com/tektoncd/pipeline/pkg/reconciler/apiserver" "github.com/tektoncd/pipeline/pkg/reconciler/pipelinerun/resources" ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" "github.com/tektoncd/pipeline/pkg/trustedresources" "github.com/tektoncd/pipeline/test" "github.com/tektoncd/pipeline/test/diff" "github.com/tektoncd/pipeline/test/parse" + resolution "github.com/tektoncd/pipeline/test/remoteresolution" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -344,8 +347,8 @@ func TestGetPipelineFunc_RemoteResolution(t *testing.T) { }} for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { - resolved := test.NewResolvedResource([]byte(tc.pipelineYAML), nil /* annotations */, sampleRefSource.DeepCopy(), nil /* data error */) - requester := test.NewRequester(resolved, nil) + resolved := resolution.NewResolvedResource([]byte(tc.pipelineYAML), nil /* annotations */, sampleRefSource.DeepCopy(), nil /* data error */) + requester := resolution.NewRequester(resolved, nil, resource.ResolverPayload{}) fn := resources.GetPipelineFunc(ctx, nil, clients, requester, &v1.PipelineRun{ ObjectMeta: metav1.ObjectMeta{Namespace: "default"}, Spec: v1.PipelineRunSpec{ @@ -399,8 +402,8 @@ func TestGetPipelineFunc_RemoteResolution_ValidationFailure(t *testing.T) { }} for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { - resolved := test.NewResolvedResource([]byte(tc.pipelineYAML), nil /* annotations */, sampleRefSource.DeepCopy(), nil /* data error */) - requester := test.NewRequester(resolved, nil) + resolved := resolution.NewResolvedResource([]byte(tc.pipelineYAML), nil /* annotations */, sampleRefSource.DeepCopy(), nil /* data error */) + requester := resolution.NewRequester(resolved, nil, resource.ResolverPayload{}) fn := resources.GetPipelineFunc(ctx, nil, clients, requester, &v1.PipelineRun{ ObjectMeta: metav1.ObjectMeta{Namespace: "default"}, Spec: v1.PipelineRunSpec{ @@ -452,16 +455,20 @@ func TestGetPipelineFunc_RemoteResolution_ReplacedParams(t *testing.T) { pipelineYAMLString, }, "\n") - resolved := test.NewResolvedResource([]byte(pipelineYAML), nil, sampleRefSource.DeepCopy(), nil) - requester := &test.Requester{ + resolved := resolution.NewResolvedResource([]byte(pipelineYAML), nil, sampleRefSource.DeepCopy(), nil) + requester := &resolution.Requester{ ResolvedResource: resolved, - Params: v1.Params{{ - Name: "foo", - Value: *v1.NewStructuredValues("bar"), - }, { - Name: "bar", - Value: *v1.NewStructuredValues("test-pipeline"), - }}, + ResolverPayload: resource.ResolverPayload{ + ResolutionSpec: &resolutionV1beta1.ResolutionRequestSpec{ + Params: v1.Params{{ + Name: "foo", + Value: *v1.NewStructuredValues("bar"), + }, { + Name: "bar", + Value: *v1.NewStructuredValues("test-pipeline"), + }}, + }, + }, } fn := resources.GetPipelineFunc(ctx, nil, clients, requester, &v1.PipelineRun{ ObjectMeta: metav1.ObjectMeta{ @@ -538,8 +545,8 @@ func TestGetPipelineFunc_RemoteResolutionInvalidData(t *testing.T) { ctx = config.ToContext(ctx, cfg) pipelineRef := &v1.PipelineRef{ResolverRef: v1.ResolverRef{Resolver: "git"}} resolvesTo := []byte("INVALID YAML") - resource := test.NewResolvedResource(resolvesTo, nil, nil, nil) - requester := test.NewRequester(resource, nil) + res := resolution.NewResolvedResource(resolvesTo, nil, nil, nil) + requester := resolution.NewRequester(res, nil, resource.ResolverPayload{}) fn := resources.GetPipelineFunc(ctx, nil, clients, requester, &v1.PipelineRun{ ObjectMeta: metav1.ObjectMeta{Namespace: "default"}, Spec: v1.PipelineRunSpec{ @@ -577,8 +584,8 @@ func TestGetPipelineFunc_V1beta1Pipeline_VerifyNoError(t *testing.T) { }, EntryPoint: "foo/bar", } - resolvedUnmatched := test.NewResolvedResource(unsignedPipelineBytes, nil, noMatchPolicyRefSource, nil) - requesterUnmatched := test.NewRequester(resolvedUnmatched, nil) + resolvedUnmatched := resolution.NewResolvedResource(unsignedPipelineBytes, nil, noMatchPolicyRefSource, nil) + requesterUnmatched := resolution.NewRequester(resolvedUnmatched, nil, resource.ResolverPayload{}) signedPipeline, err := test.GetSignedV1beta1Pipeline(unsignedPipeline, signer, "signed") if err != nil { @@ -600,8 +607,8 @@ func TestGetPipelineFunc_V1beta1Pipeline_VerifyNoError(t *testing.T) { }, EntryPoint: "foo/bar", } - resolvedMatched := test.NewResolvedResource(signedPipelineBytes, nil, matchPolicyRefSource, nil) - requesterMatched := test.NewRequester(resolvedMatched, nil) + resolvedMatched := resolution.NewResolvedResource(signedPipelineBytes, nil, matchPolicyRefSource, nil) + requesterMatched := resolution.NewRequester(resolvedMatched, nil, resource.ResolverPayload{}) pipelineRef := &v1.PipelineRef{ Name: signedPipeline.Name, @@ -647,12 +654,12 @@ func TestGetPipelineFunc_V1beta1Pipeline_VerifyNoError(t *testing.T) { warnPolicyRefSource := &v1.RefSource{ URI: " warnVP", } - resolvedUnsignedMatched := test.NewResolvedResource(unsignedPipelineBytes, nil, warnPolicyRefSource, nil) - requesterUnsignedMatched := test.NewRequester(resolvedUnsignedMatched, nil) + resolvedUnsignedMatched := resolution.NewResolvedResource(unsignedPipelineBytes, nil, warnPolicyRefSource, nil) + requesterUnsignedMatched := resolution.NewRequester(resolvedUnsignedMatched, nil, resource.ResolverPayload{}) testcases := []struct { name string - requester *test.Requester + requester *resolution.Requester verificationNoMatchPolicy string pipelinerun v1.PipelineRun policies []*v1alpha1.VerificationPolicy @@ -778,8 +785,8 @@ func TestGetPipelineFunc_V1beta1Pipeline_VerifyError(t *testing.T) { EntryPoint: "foo/bar", } - resolvedUnsigned := test.NewResolvedResource(unsignedPipelineBytes, nil, matchPolicyRefSource, nil) - requesterUnsigned := test.NewRequester(resolvedUnsigned, nil) + resolvedUnsigned := resolution.NewResolvedResource(unsignedPipelineBytes, nil, matchPolicyRefSource, nil) + requesterUnsigned := resolution.NewRequester(resolvedUnsigned, nil, resource.ResolverPayload{}) signedPipeline, err := test.GetSignedV1beta1Pipeline(unsignedPipeline, signer, "signed") if err != nil { @@ -797,8 +804,8 @@ func TestGetPipelineFunc_V1beta1Pipeline_VerifyError(t *testing.T) { }, EntryPoint: "foo/bar", } - resolvedUnmatched := test.NewResolvedResource(signedPipelineBytes, nil, noMatchPolicyRefSource, nil) - requesterUnmatched := test.NewRequester(resolvedUnmatched, nil) + resolvedUnmatched := resolution.NewResolvedResource(signedPipelineBytes, nil, noMatchPolicyRefSource, nil) + requesterUnmatched := resolution.NewRequester(resolvedUnmatched, nil, resource.ResolverPayload{}) modifiedPipeline := signedPipeline.DeepCopy() modifiedPipeline.Annotations["random"] = "attack" @@ -806,14 +813,14 @@ func TestGetPipelineFunc_V1beta1Pipeline_VerifyError(t *testing.T) { if err != nil { t.Fatal("fail to marshal pipeline", err) } - resolvedModified := test.NewResolvedResource(modifiedPipelineBytes, nil, matchPolicyRefSource, nil) - requesterModified := test.NewRequester(resolvedModified, nil) + resolvedModified := resolution.NewResolvedResource(modifiedPipelineBytes, nil, matchPolicyRefSource, nil) + requesterModified := resolution.NewRequester(resolvedModified, nil, resource.ResolverPayload{}) pipelineRef := &v1.PipelineRef{ResolverRef: v1.ResolverRef{Resolver: "git"}} testcases := []struct { name string - requester *test.Requester + requester *resolution.Requester verificationNoMatchPolicy string expectedVerificationResult *trustedresources.VerificationResult }{ @@ -906,8 +913,8 @@ func TestGetPipelineFunc_V1Pipeline_VerifyNoError(t *testing.T) { }, EntryPoint: "foo/bar", } - resolvedUnmatched := test.NewResolvedResource(unsignedPipelineBytes, nil, noMatchPolicyRefSource, nil) - requesterUnmatched := test.NewRequester(resolvedUnmatched, nil) + resolvedUnmatched := resolution.NewResolvedResource(unsignedPipelineBytes, nil, noMatchPolicyRefSource, nil) + requesterUnmatched := resolution.NewRequester(resolvedUnmatched, nil, resource.ResolverPayload{}) signedPipeline, err := getSignedV1Pipeline(unsignedV1Pipeline, signer, "signed") if err != nil { @@ -935,8 +942,8 @@ func TestGetPipelineFunc_V1Pipeline_VerifyNoError(t *testing.T) { }, EntryPoint: "foo/bar", } - resolvedMatched := test.NewResolvedResource(signedPipelineBytes, nil, matchPolicyRefSource, nil) - requesterMatched := test.NewRequester(resolvedMatched, nil) + resolvedMatched := resolution.NewResolvedResource(signedPipelineBytes, nil, matchPolicyRefSource, nil) + requesterMatched := resolution.NewRequester(resolvedMatched, nil, resource.ResolverPayload{}) pipelineRef := &v1.PipelineRef{ Name: signedPipeline.Name, @@ -980,12 +987,12 @@ func TestGetPipelineFunc_V1Pipeline_VerifyNoError(t *testing.T) { warnPolicyRefSource := &v1.RefSource{ URI: " warnVP", } - resolvedUnsignedMatched := test.NewResolvedResource(unsignedPipelineBytes, nil, warnPolicyRefSource, nil) - requesterUnsignedMatched := test.NewRequester(resolvedUnsignedMatched, nil) + resolvedUnsignedMatched := resolution.NewResolvedResource(unsignedPipelineBytes, nil, warnPolicyRefSource, nil) + requesterUnsignedMatched := resolution.NewRequester(resolvedUnsignedMatched, nil, resource.ResolverPayload{}) testcases := []struct { name string - requester *test.Requester + requester *resolution.Requester verificationNoMatchPolicy string pipelinerun v1.PipelineRun policies []*v1alpha1.VerificationPolicy @@ -1110,8 +1117,8 @@ func TestGetPipelineFunc_V1Pipeline_VerifyError(t *testing.T) { EntryPoint: "foo/bar", } - resolvedUnsigned := test.NewResolvedResource(unsignedPipelineBytes, nil, matchPolicyRefSource, nil) - requesterUnsigned := test.NewRequester(resolvedUnsigned, nil) + resolvedUnsigned := resolution.NewResolvedResource(unsignedPipelineBytes, nil, matchPolicyRefSource, nil) + requesterUnsigned := resolution.NewRequester(resolvedUnsigned, nil, resource.ResolverPayload{}) signedPipeline, err := getSignedV1Pipeline(unsignedV1Pipeline, signer, "signed") if err != nil { @@ -1129,8 +1136,8 @@ func TestGetPipelineFunc_V1Pipeline_VerifyError(t *testing.T) { }, EntryPoint: "foo/bar", } - resolvedUnmatched := test.NewResolvedResource(signedPipelineBytes, nil, noMatchPolicyRefSource, nil) - requesterUnmatched := test.NewRequester(resolvedUnmatched, nil) + resolvedUnmatched := resolution.NewResolvedResource(signedPipelineBytes, nil, noMatchPolicyRefSource, nil) + requesterUnmatched := resolution.NewRequester(resolvedUnmatched, nil, resource.ResolverPayload{}) modifiedPipeline := signedPipeline.DeepCopy() modifiedPipeline.Annotations["random"] = "attack" @@ -1138,14 +1145,14 @@ func TestGetPipelineFunc_V1Pipeline_VerifyError(t *testing.T) { if err != nil { t.Fatal("fail to marshal pipeline", err) } - resolvedModified := test.NewResolvedResource(modifiedPipelineBytes, nil, matchPolicyRefSource, nil) - requesterModified := test.NewRequester(resolvedModified, nil) + resolvedModified := resolution.NewResolvedResource(modifiedPipelineBytes, nil, matchPolicyRefSource, nil) + requesterModified := resolution.NewRequester(resolvedModified, nil, resource.ResolverPayload{}) pipelineRef := &v1.PipelineRef{ResolverRef: v1.ResolverRef{Resolver: "git"}} testcases := []struct { name string - requester *test.Requester + requester *resolution.Requester verificationNoMatchPolicy string expectedVerificationResult *trustedresources.VerificationResult }{ @@ -1221,8 +1228,8 @@ func TestGetPipelineFunc_GetFuncError(t *testing.T) { t.Fatal("fail to marshal pipeline", err) } - resolvedUnsigned := test.NewResolvedResource(unsignedPipelineBytes, nil, sampleRefSource.DeepCopy(), nil) - requesterUnsigned := test.NewRequester(resolvedUnsigned, nil) + resolvedUnsigned := resolution.NewResolvedResource(unsignedPipelineBytes, nil, sampleRefSource.DeepCopy(), nil) + requesterUnsigned := resolution.NewRequester(resolvedUnsigned, nil, resource.ResolverPayload{}) resolvedUnsigned.DataErr = errors.New("resolution error") prResolutionError := &v1.PipelineRun{ @@ -1242,7 +1249,7 @@ func TestGetPipelineFunc_GetFuncError(t *testing.T) { testcases := []struct { name string - requester *test.Requester + requester *resolution.Requester pipelinerun v1.PipelineRun expectedErr error }{ diff --git a/pkg/reconciler/taskrun/controller.go b/pkg/reconciler/taskrun/controller.go index 451c78f9795..024abd29373 100644 --- a/pkg/reconciler/taskrun/controller.go +++ b/pkg/reconciler/taskrun/controller.go @@ -31,7 +31,7 @@ import ( "github.com/tektoncd/pipeline/pkg/pod" cloudeventclient "github.com/tektoncd/pipeline/pkg/reconciler/events/cloudevent" "github.com/tektoncd/pipeline/pkg/reconciler/volumeclaim" - resolution "github.com/tektoncd/pipeline/pkg/resolution/resource" + resolution "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" "github.com/tektoncd/pipeline/pkg/spire" "github.com/tektoncd/pipeline/pkg/taskrunmetrics" "github.com/tektoncd/pipeline/pkg/tracing" diff --git a/pkg/reconciler/taskrun/resources/taskref.go b/pkg/reconciler/taskrun/resources/taskref.go index 7bddf0b0523..872af8a787a 100644 --- a/pkg/reconciler/taskrun/resources/taskref.go +++ b/pkg/reconciler/taskrun/resources/taskref.go @@ -25,11 +25,12 @@ import ( v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + resolutionV1beta1 "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" clientset "github.com/tektoncd/pipeline/pkg/client/clientset/versioned" "github.com/tektoncd/pipeline/pkg/reconciler/apiserver" "github.com/tektoncd/pipeline/pkg/remote" - "github.com/tektoncd/pipeline/pkg/remote/resolution" - remoteresource "github.com/tektoncd/pipeline/pkg/resolution/resource" + "github.com/tektoncd/pipeline/pkg/remoteresolution/remote/resolution" + remoteresource "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" "github.com/tektoncd/pipeline/pkg/trustedresources" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -108,7 +109,14 @@ func GetTaskFunc(ctx context.Context, k8s kubernetes.Interface, tekton clientset } else { replacedParams = append(replacedParams, tr.Params...) } - resolver := resolution.NewResolver(requester, owner, string(tr.Resolver), trName, namespace, replacedParams) + resolverPayload := remoteresource.ResolverPayload{ + Name: trName, + Namespace: namespace, + ResolutionSpec: &resolutionV1beta1.ResolutionRequestSpec{ + Params: replacedParams, + }, + } + resolver := resolution.NewResolver(requester, owner, string(tr.Resolver), resolverPayload) return resolveTask(ctx, resolver, name, namespace, kind, k8s, tekton, verificationPolicies) } @@ -136,7 +144,14 @@ func GetStepActionFunc(tekton clientset.Interface, k8s kubernetes.Interface, req return func(ctx context.Context, name string) (*v1alpha1.StepAction, *v1.RefSource, error) { // Perform params replacements for StepAction resolver params ApplyParameterSubstitutionInResolverParams(tr, step) - resolver := resolution.NewResolver(requester, tr, string(step.Ref.Resolver), trName, namespace, step.Ref.Params) + resolverPayload := remoteresource.ResolverPayload{ + Name: trName, + Namespace: namespace, + ResolutionSpec: &resolutionV1beta1.ResolutionRequestSpec{ + Params: step.Ref.Params, + }, + } + resolver := resolution.NewResolver(requester, tr, string(step.Ref.Resolver), resolverPayload) return resolveStepAction(ctx, resolver, name, namespace, k8s, tekton) } } diff --git a/pkg/reconciler/taskrun/resources/taskref_test.go b/pkg/reconciler/taskrun/resources/taskref_test.go index 1f81947dd95..9bf6c18ca38 100644 --- a/pkg/reconciler/taskrun/resources/taskref_test.go +++ b/pkg/reconciler/taskrun/resources/taskref_test.go @@ -34,13 +34,16 @@ import ( v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + resolutionV1beta1 "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" "github.com/tektoncd/pipeline/pkg/client/clientset/versioned/fake" "github.com/tektoncd/pipeline/pkg/reconciler/apiserver" "github.com/tektoncd/pipeline/pkg/reconciler/taskrun/resources" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" "github.com/tektoncd/pipeline/pkg/trustedresources" "github.com/tektoncd/pipeline/test" "github.com/tektoncd/pipeline/test/diff" "github.com/tektoncd/pipeline/test/parse" + resolution "github.com/tektoncd/pipeline/test/remoteresolution" corev1 "k8s.io/api/core/v1" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -897,8 +900,8 @@ func TestGetStepActionFunc_RemoteResolution_Success(t *testing.T) { }} for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { - resolved := test.NewResolvedResource([]byte(tc.stepActionYAML), nil /* annotations */, sampleRefSource.DeepCopy(), nil /* data error */) - requester := test.NewRequester(resolved, nil) + resolved := resolution.NewResolvedResource([]byte(tc.stepActionYAML), nil /* annotations */, sampleRefSource.DeepCopy(), nil /* data error */) + requester := resolution.NewRequester(resolved, nil, resource.ResolverPayload{}) tr := &v1.TaskRun{ ObjectMeta: metav1.ObjectMeta{Namespace: "default"}, Spec: v1.TaskRunSpec{ @@ -958,8 +961,8 @@ func TestGetStepActionFunc_RemoteResolution_Error(t *testing.T) { for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { - resource := test.NewResolvedResource(tc.resolvesTo, nil, nil, nil) - requester := test.NewRequester(resource, nil) + res := resolution.NewResolvedResource(tc.resolvesTo, nil, nil, nil) + requester := resolution.NewRequester(res, nil, resource.ResolverPayload{}) tr := &v1.TaskRun{ ObjectMeta: metav1.ObjectMeta{Namespace: "default"}, Spec: v1.TaskRunSpec{ @@ -1090,8 +1093,8 @@ func TestGetTaskFunc_RemoteResolution(t *testing.T) { }} for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { - resolved := test.NewResolvedResource([]byte(tc.taskYAML), nil /* annotations */, sampleRefSource.DeepCopy(), nil /* data error */) - requester := test.NewRequester(resolved, nil) + resolved := resolution.NewResolvedResource([]byte(tc.taskYAML), nil /* annotations */, sampleRefSource.DeepCopy(), nil /* data error */) + requester := resolution.NewRequester(resolved, nil, resource.ResolverPayload{}) tr := &v1.TaskRun{ ObjectMeta: metav1.ObjectMeta{Namespace: "default"}, Spec: v1.TaskRunSpec{ @@ -1157,8 +1160,8 @@ func TestGetTaskFunc_RemoteResolution_ValidationFailure(t *testing.T) { }} for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { - resolved := test.NewResolvedResource([]byte(tc.taskYAML), nil /* annotations */, sampleRefSource.DeepCopy(), nil /* data error */) - requester := test.NewRequester(resolved, nil) + resolved := resolution.NewResolvedResource([]byte(tc.taskYAML), nil /* annotations */, sampleRefSource.DeepCopy(), nil /* data error */) + requester := resolution.NewRequester(resolved, nil, resource.ResolverPayload{}) tektonclient := fake.NewSimpleClientset() fn := resources.GetTaskFunc(ctx, nil, tektonclient, requester, &v1.TaskRun{ ObjectMeta: metav1.ObjectMeta{Namespace: "default"}, @@ -1208,16 +1211,20 @@ func TestGetTaskFunc_RemoteResolution_ReplacedParams(t *testing.T) { taskYAMLString, }, "\n") - resolved := test.NewResolvedResource([]byte(taskYAML), nil, sampleRefSource.DeepCopy(), nil) - requester := &test.Requester{ + resolved := resolution.NewResolvedResource([]byte(taskYAML), nil, sampleRefSource.DeepCopy(), nil) + requester := &resolution.Requester{ ResolvedResource: resolved, - Params: v1.Params{{ - Name: "foo", - Value: *v1.NewStructuredValues("bar"), - }, { - Name: "bar", - Value: *v1.NewStructuredValues("test-task"), - }}, + ResolverPayload: resource.ResolverPayload{ + ResolutionSpec: &resolutionV1beta1.ResolutionRequestSpec{ + Params: v1.Params{{ + Name: "foo", + Value: *v1.NewStructuredValues("bar"), + }, { + Name: "bar", + Value: *v1.NewStructuredValues("test-task"), + }}, + }, + }, } tr := &v1.TaskRun{ ObjectMeta: metav1.ObjectMeta{ @@ -1293,8 +1300,8 @@ func TestGetPipelineFunc_RemoteResolutionInvalidData(t *testing.T) { ctx = config.ToContext(ctx, cfg) taskRef := &v1.TaskRef{ResolverRef: v1.ResolverRef{Resolver: "git"}} resolvesTo := []byte("INVALID YAML") - resource := test.NewResolvedResource(resolvesTo, nil, nil, nil) - requester := test.NewRequester(resource, nil) + res := resolution.NewResolvedResource(resolvesTo, nil, nil, nil) + requester := resolution.NewRequester(res, nil, resource.ResolverPayload{}) tr := &v1.TaskRun{ ObjectMeta: metav1.ObjectMeta{Namespace: "default"}, Spec: v1.TaskRunSpec{ @@ -1355,7 +1362,7 @@ func TestGetTaskFunc_V1beta1Task_VerifyNoError(t *testing.T) { testcases := []struct { name string - requester *test.Requester + requester *resolution.Requester verificationNoMatchPolicy string policies []*v1alpha1.VerificationPolicy expected runtime.Object @@ -1484,7 +1491,7 @@ func TestGetTaskFunc_V1beta1Task_VerifyError(t *testing.T) { testcases := []struct { name string - requester *test.Requester + requester *resolution.Requester verificationNoMatchPolicy string expected *v1.Task expectedErr error @@ -1621,7 +1628,7 @@ func TestGetTaskFunc_V1Task_VerifyNoError(t *testing.T) { testcases := []struct { name string - requester *test.Requester + requester *resolution.Requester verificationNoMatchPolicy string policies []*v1alpha1.VerificationPolicy expected runtime.Object @@ -1750,7 +1757,7 @@ func TestGetTaskFunc_V1Task_VerifyError(t *testing.T) { testcases := []struct { name string - requester *test.Requester + requester *resolution.Requester verificationNoMatchPolicy string expected *v1.Task expectedErr error @@ -1837,8 +1844,8 @@ func TestGetTaskFunc_GetFuncError(t *testing.T) { t.Fatal("fail to marshal task", err) } - resolvedUnsigned := test.NewResolvedResource(unsignedTaskBytes, nil, sampleRefSource.DeepCopy(), nil) - requesterUnsigned := test.NewRequester(resolvedUnsigned, nil) + resolvedUnsigned := resolution.NewResolvedResource(unsignedTaskBytes, nil, sampleRefSource.DeepCopy(), nil) + requesterUnsigned := resolution.NewRequester(resolvedUnsigned, nil, resource.ResolverPayload{}) resolvedUnsigned.DataErr = errors.New("resolution error") trResolutionError := &v1.TaskRun{ @@ -1856,7 +1863,7 @@ func TestGetTaskFunc_GetFuncError(t *testing.T) { testcases := []struct { name string - requester *test.Requester + requester *resolution.Requester taskrun v1.TaskRun expectedErr error }{ @@ -1932,9 +1939,9 @@ spec: - name: foo ` -func bytesToRequester(data []byte, source *v1.RefSource) *test.Requester { - resolved := test.NewResolvedResource(data, nil, source, nil) - requester := test.NewRequester(resolved, nil) +func bytesToRequester(data []byte, source *v1.RefSource) *resolution.Requester { + resolved := resolution.NewResolvedResource(data, nil, source, nil) + requester := resolution.NewRequester(resolved, nil, resource.ResolverPayload{}) return requester } diff --git a/pkg/reconciler/taskrun/resources/taskspec.go b/pkg/reconciler/taskrun/resources/taskspec.go index 64d71df04e8..955154911c9 100644 --- a/pkg/reconciler/taskrun/resources/taskspec.go +++ b/pkg/reconciler/taskrun/resources/taskspec.go @@ -25,7 +25,7 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" clientset "github.com/tektoncd/pipeline/pkg/client/clientset/versioned" resolutionutil "github.com/tektoncd/pipeline/pkg/internal/resolution" - remoteresource "github.com/tektoncd/pipeline/pkg/resolution/resource" + remoteresource "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" "github.com/tektoncd/pipeline/pkg/trustedresources" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" diff --git a/pkg/reconciler/taskrun/taskrun.go b/pkg/reconciler/taskrun/taskrun.go index 4259f1f9279..ebd744d05b7 100644 --- a/pkg/reconciler/taskrun/taskrun.go +++ b/pkg/reconciler/taskrun/taskrun.go @@ -47,7 +47,7 @@ import ( "github.com/tektoncd/pipeline/pkg/reconciler/taskrun/resources" "github.com/tektoncd/pipeline/pkg/reconciler/volumeclaim" "github.com/tektoncd/pipeline/pkg/remote" - resolution "github.com/tektoncd/pipeline/pkg/resolution/resource" + resolution "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" "github.com/tektoncd/pipeline/pkg/spire" "github.com/tektoncd/pipeline/pkg/taskrunmetrics" _ "github.com/tektoncd/pipeline/pkg/taskrunmetrics/fake" // Make sure the taskrunmetrics are setup diff --git a/pkg/remote/resolution/error.go b/pkg/remote/resolution/error.go index 05022c5f8cb..9621060e074 100644 --- a/pkg/remote/resolution/error.go +++ b/pkg/remote/resolution/error.go @@ -36,7 +36,7 @@ var ( // InvalidRuntimeObjectError is returned when remote resolution // succeeded but the returned data is not a valid runtime.Object. type InvalidRuntimeObjectError struct { - original error + Original error } // ErrorInvalidRuntimeObject is an alias to InvalidRuntimeObjectError. @@ -51,12 +51,12 @@ var ( // Error returns the string representation of this error. func (e *InvalidRuntimeObjectError) Error() string { - return fmt.Sprintf("invalid runtime object: %v", e.original) + return fmt.Sprintf("invalid runtime object: %v", e.Original) } // Unwrap returns the underlying original error. func (e *InvalidRuntimeObjectError) Unwrap() error { - return e.original + return e.Original } // Is returns true if the given error coerces into an error of this type. @@ -68,7 +68,7 @@ func (e *InvalidRuntimeObjectError) Is(that error) bool { // attempting to access the resolved data failed. An example of this // type of error would be if a ResolutionRequest contained malformed base64. type DataAccessError struct { - original error + Original error } // ErrorAccessingData is an alias to DataAccessError @@ -83,12 +83,12 @@ var ( // Error returns the string representation of this error. func (e *DataAccessError) Error() string { - return fmt.Sprintf("error accessing data from remote resource: %v", e.original) + return fmt.Sprintf("error accessing data from remote resource: %v", e.Original) } // Unwrap returns the underlying original error. func (e *DataAccessError) Unwrap() error { - return e.original + return e.Original } // Is returns true if the given error coerces into an error of this type. diff --git a/pkg/remote/resolution/resolver.go b/pkg/remote/resolution/resolver.go index 772b39e416a..fb164924f03 100644 --- a/pkg/remote/resolution/resolver.go +++ b/pkg/remote/resolution/resolver.go @@ -63,6 +63,27 @@ func (resolver *Resolver) Get(ctx context.Context, _, _ string) (runtime.Object, return nil, nil, fmt.Errorf("error building request for remote resource: %w", err) } resolved, err := resolver.requester.Submit(ctx, resolverName, req) + return ResolvedRequest(resolved, err) +} + +// List implements remote.Resolver but is unused for remote resolution. +func (resolver *Resolver) List(_ context.Context) ([]remote.ResolvedObject, error) { + return nil, nil +} + +func buildRequest(resolverName string, owner kmeta.OwnerRefable, name string, namespace string, params v1.Params) (*resolutionRequest, error) { + name, namespace, err := remoteresource.GetNameAndNamespace(resolverName, owner, name, namespace, params) + if err != nil { + return nil, err + } + req := &resolutionRequest{ + Request: remoteresource.NewRequest(name, namespace, params), + owner: owner, + } + return req, nil +} + +func ResolvedRequest(resolved resolutioncommon.ResolvedResource, err error) (runtime.Object, *v1.RefSource, error) { switch { case errors.Is(err, resolutioncommon.ErrRequestInProgress): return nil, nil, remote.ErrRequestInProgress @@ -74,39 +95,11 @@ func (resolver *Resolver) Get(ctx context.Context, _, _ string) (runtime.Object, } data, err := resolved.Data() if err != nil { - return nil, nil, &DataAccessError{original: err} + return nil, nil, &DataAccessError{Original: err} } obj, _, err := scheme.Codecs.UniversalDeserializer().Decode(data, nil, nil) if err != nil { - return nil, nil, &InvalidRuntimeObjectError{original: err} + return nil, nil, &InvalidRuntimeObjectError{Original: err} } return obj, resolved.RefSource(), nil } - -// List implements remote.Resolver but is unused for remote resolution. -func (resolver *Resolver) List(_ context.Context) ([]remote.ResolvedObject, error) { - return nil, nil -} - -func buildRequest(resolverName string, owner kmeta.OwnerRefable, name string, namespace string, params v1.Params) (*resolutionRequest, error) { - if name == "" { - name = owner.GetObjectMeta().GetName() - namespace = owner.GetObjectMeta().GetNamespace() - } - if namespace == "" { - namespace = "default" - } - // Generating a deterministic name for the resource request - // prevents multiple requests being issued for the same - // pipelinerun's pipelineRef or taskrun's taskRef. - remoteResourceBaseName := namespace + "/" + name - name, err := remoteresource.GenerateDeterministicName(resolverName, remoteResourceBaseName, params) - if err != nil { - return nil, fmt.Errorf("error generating name for taskrun %s/%s: %w", namespace, name, err) - } - req := &resolutionRequest{ - Request: remoteresource.NewRequest(name, namespace, params), - owner: owner, - } - return req, nil -} diff --git a/pkg/remote/resolution/resolver_test.go b/pkg/remote/resolution/resolver_test.go index 8e900ba50ea..6f078ac2851 100644 --- a/pkg/remote/resolution/resolver_test.go +++ b/pkg/remote/resolution/resolver_test.go @@ -23,8 +23,8 @@ import ( "github.com/tektoncd/pipeline/pkg/remote" resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" remoteresource "github.com/tektoncd/pipeline/pkg/resolution/resource" - "github.com/tektoncd/pipeline/test" "github.com/tektoncd/pipeline/test/diff" + resolution "github.com/tektoncd/pipeline/test/resolution" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/pkg/kmeta" ) @@ -60,11 +60,11 @@ func TestGet_Successful(t *testing.T) { Namespace: "bar", }, } - resolved := &test.ResolvedResource{ + resolved := &resolution.ResolvedResource{ ResolvedData: tc.resolvedData, ResolvedAnnotations: tc.resolvedAnnotations, } - requester := &test.Requester{ + requester := &resolution.Requester{ SubmitErr: nil, ResolvedResource: resolved, } @@ -77,11 +77,11 @@ func TestGet_Successful(t *testing.T) { func TestGet_Errors(t *testing.T) { genericError := errors.New("uh oh something bad happened") - notARuntimeObject := &test.ResolvedResource{ + notARuntimeObject := &resolution.ResolvedResource{ ResolvedData: []byte(">:)"), ResolvedAnnotations: nil, } - invalidDataResource := &test.ResolvedResource{ + invalidDataResource := &resolution.ResolvedResource{ DataErr: errors.New("data access error"), ResolvedAnnotations: nil, } @@ -117,7 +117,7 @@ func TestGet_Errors(t *testing.T) { Namespace: "bar", }, } - requester := &test.Requester{ + requester := &resolution.Requester{ SubmitErr: tc.submitErr, ResolvedResource: tc.resolvedResource, } diff --git a/pkg/remoteresolution/doc.go b/pkg/remoteresolution/doc.go new file mode 100644 index 00000000000..83734f5ddd9 --- /dev/null +++ b/pkg/remoteresolution/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package remoteresolution contains the upgraded remote resolution framework. +This was necessary to ensure backwards compatibility with the existing framework. + +This package is subject to further refactoring and changes. +*/ +package remoteresolution diff --git a/pkg/remoteresolution/remote/resolution/doc.go b/pkg/remoteresolution/remote/resolution/doc.go new file mode 100644 index 00000000000..3fc8f5f7a8e --- /dev/null +++ b/pkg/remoteresolution/remote/resolution/doc.go @@ -0,0 +1,24 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package resolution contains the upgraded remote resolution framework. +It is equivalent to `pkg/remote/resolution`. +This was necessary to ensure backwards compatibility with the existing framework. + +This package is subject to further refactoring and changes. +*/ +package resolution diff --git a/pkg/remoteresolution/remote/resolution/request.go b/pkg/remoteresolution/remote/resolution/request.go new file mode 100644 index 00000000000..5a22f414014 --- /dev/null +++ b/pkg/remoteresolution/remote/resolution/request.go @@ -0,0 +1,32 @@ +/* +Copyright 2024 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resolution + +import ( + resolution "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/kmeta" +) + +var _ resolution.Request = &resolutionRequest{} +var _ resolution.OwnedRequest = &resolutionRequest{} + +type resolutionRequest struct { + resolution.Request + owner kmeta.OwnerRefable +} + +func (req *resolutionRequest) OwnerRef() metav1.OwnerReference { + return *kmeta.NewControllerRef(req.owner) +} diff --git a/pkg/remoteresolution/remote/resolution/resolver.go b/pkg/remoteresolution/remote/resolution/resolver.go new file mode 100644 index 00000000000..85836addbeb --- /dev/null +++ b/pkg/remoteresolution/remote/resolution/resolver.go @@ -0,0 +1,91 @@ +/* +Copyright 2024 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resolution + +import ( + "context" + "fmt" + + v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "github.com/tektoncd/pipeline/pkg/remote" + resolution "github.com/tektoncd/pipeline/pkg/remote/resolution" + remoteresource "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" + resource "github.com/tektoncd/pipeline/pkg/resolution/resource" + "k8s.io/apimachinery/pkg/runtime" + "knative.dev/pkg/kmeta" +) + +// Resolver implements remote.Resolver and encapsulates the majority of +// code required to interface with the tektoncd/resolution project. It +// is used to make async requests for resources like pipelines from +// remote places like git repos. +type Resolver struct { + requester remoteresource.Requester + owner kmeta.OwnerRefable + resolverName string + resolverPayload remoteresource.ResolverPayload +} + +var _ remote.Resolver = &Resolver{} + +// NewResolver returns an implementation of remote.Resolver capable +// of performing asynchronous remote resolution. +func NewResolver(requester remoteresource.Requester, owner kmeta.OwnerRefable, resolverName string, resolverPayload remoteresource.ResolverPayload) remote.Resolver { + return &Resolver{ + requester: requester, + owner: owner, + resolverName: resolverName, + resolverPayload: resolverPayload, + } +} + +// Get implements remote.Resolver. +func (resolver *Resolver) Get(ctx context.Context, _, _ string) (runtime.Object, *v1.RefSource, error) { + resolverName := remoteresource.ResolverName(resolver.resolverName) + req, err := buildRequest(resolver.resolverName, resolver.owner, &resolver.resolverPayload) + if err != nil { + return nil, nil, fmt.Errorf("error building request for remote resource: %w", err) + } + resolved, err := resolver.requester.Submit(ctx, resolverName, req) + return resolution.ResolvedRequest(resolved, err) +} + +// List implements remote.Resolver but is unused for remote resolution. +func (resolver *Resolver) List(_ context.Context) ([]remote.ResolvedObject, error) { + return nil, nil +} + +func buildRequest(resolverName string, owner kmeta.OwnerRefable, resolverPayload *remoteresource.ResolverPayload) (*resolutionRequest, error) { + var name string + var namespace string + var params v1.Params + if resolverPayload != nil { + name = resolverPayload.Name + namespace = resolverPayload.Namespace + if resolverPayload.ResolutionSpec != nil { + params = resolverPayload.ResolutionSpec.Params + } + } + name, namespace, err := resource.GetNameAndNamespace(resolverName, owner, name, namespace, params) + if err != nil { + return nil, err + } + resolverPayload.Name = name + resolverPayload.Namespace = namespace + req := &resolutionRequest{ + Request: remoteresource.NewRequest(*resolverPayload), + owner: owner, + } + return req, nil +} diff --git a/pkg/remoteresolution/remote/resolution/resolver_test.go b/pkg/remoteresolution/remote/resolution/resolver_test.go new file mode 100644 index 00000000000..e93f43ef4f2 --- /dev/null +++ b/pkg/remoteresolution/remote/resolution/resolver_test.go @@ -0,0 +1,181 @@ +/* +Copyright 2024 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resolution + +import ( + "context" + "errors" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + "github.com/tektoncd/pipeline/pkg/remote" + "github.com/tektoncd/pipeline/pkg/remote/resolution" + remoteresource "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" + "github.com/tektoncd/pipeline/pkg/resolution/common" + "github.com/tektoncd/pipeline/pkg/resolution/resource" + "github.com/tektoncd/pipeline/test/diff" + test "github.com/tektoncd/pipeline/test/remoteresolution" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/kmeta" +) + +var pipelineBytes = []byte(` +kind: Pipeline +apiVersion: tekton.dev/v1beta1 +metadata: + name: foo +spec: + tasks: + - name: task1 + taskSpec: + steps: + - name: step1 + image: ubuntu + script: | + echo "hello world!" +`) + +func TestGet_Successful(t *testing.T) { + for _, tc := range []struct { + resolvedData []byte + resolvedAnnotations map[string]string + }{{ + resolvedData: pipelineBytes, + resolvedAnnotations: nil, + }} { + ctx := context.Background() + owner := &v1beta1.PipelineRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + }, + } + resolved := &test.ResolvedResource{ + ResolvedData: tc.resolvedData, + ResolvedAnnotations: tc.resolvedAnnotations, + } + requester := &test.Requester{ + SubmitErr: nil, + ResolvedResource: resolved, + } + resolver := NewResolver(requester, owner, "git", remoteresource.ResolverPayload{}) + if _, _, err := resolver.Get(ctx, "foo", "bar"); err != nil { + t.Fatalf("unexpected error: %v", err) + } + } +} + +func TestGet_Errors(t *testing.T) { + genericError := errors.New("uh oh something bad happened") + notARuntimeObject := &test.ResolvedResource{ + ResolvedData: []byte(">:)"), + ResolvedAnnotations: nil, + } + invalidDataResource := &test.ResolvedResource{ + DataErr: errors.New("data access error"), + ResolvedAnnotations: nil, + } + for _, tc := range []struct { + submitErr error + expectedGetErr error + resolvedResource remoteresource.ResolvedResource + }{{ + submitErr: common.ErrRequestInProgress, + expectedGetErr: remote.ErrRequestInProgress, + resolvedResource: nil, + }, { + submitErr: nil, + expectedGetErr: resolution.ErrNilResource, + resolvedResource: nil, + }, { + submitErr: genericError, + expectedGetErr: genericError, + resolvedResource: nil, + }, { + submitErr: nil, + expectedGetErr: &resolution.InvalidRuntimeObjectError{}, + resolvedResource: notARuntimeObject, + }, { + submitErr: nil, + expectedGetErr: &resolution.DataAccessError{}, + resolvedResource: invalidDataResource, + }} { + ctx := context.Background() + owner := &v1beta1.PipelineRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + }, + } + requester := &test.Requester{ + SubmitErr: tc.submitErr, + ResolvedResource: tc.resolvedResource, + } + resolver := NewResolver(requester, owner, "git", remoteresource.ResolverPayload{}) + obj, refSource, err := resolver.Get(ctx, "foo", "bar") + if obj != nil { + t.Errorf("received unexpected resolved resource") + } + if refSource != nil { + t.Errorf("expected refSource is nil, but received %v", refSource) + } + if !errors.Is(err, tc.expectedGetErr) { + t.Fatalf("expected %v received %v", tc.expectedGetErr, err) + } + } +} + +func TestBuildRequestV2(t *testing.T) { + for _, tc := range []struct { + name string + targetName string + targetNamespace string + }{{ + name: "just owner", + }, { + name: "with target name and namespace", + targetName: "some-object", + targetNamespace: "some-ns", + }} { + t.Run(tc.name, func(t *testing.T) { + owner := &v1beta1.PipelineRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "foo", + Namespace: "bar", + }, + } + + rr := &remoteresource.ResolverPayload{Name: tc.targetName, Namespace: tc.targetNamespace} + req, err := buildRequest("git", owner, rr) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if d := cmp.Diff(*kmeta.NewControllerRef(owner), req.OwnerRef()); d != "" { + t.Errorf("expected matching owner ref but got %s", diff.PrintWantGot(d)) + } + reqNameBase := owner.Namespace + "/" + owner.Name + if tc.targetName != "" { + reqNameBase = tc.targetNamespace + "/" + tc.targetName + } + expectedReqName, err := resource.GenerateDeterministicNameFromSpec("git", reqNameBase, rr.ResolutionSpec) + if err != nil { + t.Fatalf("unexpected error: %v", err) + } + if expectedReqName != req.ResolverPayload().Name { + t.Errorf("expected request name %s, but was %s", expectedReqName, req.ResolverPayload().Name) + } + }) + } +} diff --git a/pkg/remoteresolution/resolver/bundle/resolver.go b/pkg/remoteresolution/resolver/bundle/resolver.go new file mode 100644 index 00000000000..85abd28672f --- /dev/null +++ b/pkg/remoteresolution/resolver/bundle/resolver.go @@ -0,0 +1,78 @@ +/* + Copyright 2024 The Tekton Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package bundle + +import ( + "context" + + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" + "github.com/tektoncd/pipeline/pkg/resolution/common" + "github.com/tektoncd/pipeline/pkg/resolution/resolver/bundle" + resolutionframework "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" + "k8s.io/client-go/kubernetes" + "knative.dev/pkg/client/injection/kube/client" +) + +const ( + // LabelValueBundleResolverType is the value to use for the + // resolution.tekton.dev/type label on resource requests + LabelValueBundleResolverType string = "bundles" + + // BundleResolverName is the name that the bundle resolver should be associated with. + BundleResolverName = "bundleresolver" +) + +var _ framework.Resolver = &Resolver{} + +// Resolver implements a framework.Resolver that can fetch files from OCI bundles. +type Resolver struct { + kubeClientSet kubernetes.Interface +} + +// Initialize sets up any dependencies needed by the Resolver. None atm. +func (r *Resolver) Initialize(ctx context.Context) error { + r.kubeClientSet = client.Get(ctx) + return nil +} + +// GetName returns a string name to refer to this Resolver by. +func (r *Resolver) GetName(context.Context) string { + return BundleResolverName +} + +// GetConfigName returns the name of the bundle resolver's configmap. +func (r *Resolver) GetConfigName(context.Context) string { + return bundle.ConfigMapName +} + +// GetSelector returns a map of labels to match requests to this Resolver. +func (r *Resolver) GetSelector(context.Context) map[string]string { + return map[string]string{ + common.LabelKeyResolverType: LabelValueBundleResolverType, + } +} + +// Validate ensures reqolution request spec from a request are as expected. +func (r *Resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestSpec) error { + return bundle.ValidateParams(ctx, req.Params) +} + +// Resolve uses the given params to resolve the requested file or resource. +func (r *Resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (resolutionframework.ResolvedResource, error) { + return bundle.ResolveRequest(ctx, r.kubeClientSet, req) +} diff --git a/pkg/remoteresolution/resolver/bundle/resolver_test.go b/pkg/remoteresolution/resolver/bundle/resolver_test.go new file mode 100644 index 00000000000..9ce0b25f1d7 --- /dev/null +++ b/pkg/remoteresolution/resolver/bundle/resolver_test.go @@ -0,0 +1,610 @@ +/* + Copyright 2024 The Tekton Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package bundle_test + +import ( + "context" + "errors" + "fmt" + "net/http/httptest" + "net/url" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-containerregistry/pkg/registry" + resolverconfig "github.com/tektoncd/pipeline/pkg/apis/config/resolver" + pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/internal/resolution" + ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" + bundle "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/bundle" + 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" + frameworktesting "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework/testing" + "github.com/tektoncd/pipeline/test" + "github.com/tektoncd/pipeline/test/diff" + corev1 "k8s.io/api/core/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime" + ktesting "k8s.io/client-go/testing" + "knative.dev/pkg/system" + _ "knative.dev/pkg/system/testing" // Setup system.Namespace() + "sigs.k8s.io/yaml" +) + +const ( + disabledError = "cannot handle resolution request, enable-bundles-resolver feature flag not true" +) + +func TestGetSelector(t *testing.T) { + resolver := bundle.Resolver{} + sel := resolver.GetSelector(context.Background()) + if typ, has := sel[resolutioncommon.LabelKeyResolverType]; !has { + t.Fatalf("unexpected selector: %v", sel) + } else if typ != bundle.LabelValueBundleResolverType { + t.Fatalf("unexpected type: %q", typ) + } +} + +func TestValidate(t *testing.T) { + resolver := bundle.Resolver{} + + 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.ParamImagePullSecret, + Value: *pipelinev1.NewStructuredValues("baz"), + }} + req := v1beta1.ResolutionRequestSpec{Params: paramsWithTask} + if err := resolver.Validate(context.Background(), &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.ParamImagePullSecret, + 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) + } +} + +func TestValidateDisabled(t *testing.T) { + resolver := bundle.Resolver{} + + var err error + + params := []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.ParamImagePullSecret, + Value: *pipelinev1.NewStructuredValues("baz"), + }} + req := v1beta1.ResolutionRequestSpec{Params: params} + err = resolver.Validate(resolverDisabledContext(), &req) + if err == nil { + t.Fatalf("expected disabled err") + } + + if d := cmp.Diff(disabledError, err.Error()); d != "" { + t.Errorf("unexpected error: %s", diff.PrintWantGot(d)) + } +} + +func TestValidateMissing(t *testing.T) { + resolver := bundle.Resolver{} + + var err error + + paramsMissingBundle := []pipelinev1.Param{{ + Name: bundleresolution.ParamKind, + Value: *pipelinev1.NewStructuredValues("task"), + }, { + Name: bundleresolution.ParamName, + Value: *pipelinev1.NewStructuredValues("foo"), + }, { + Name: bundleresolution.ParamImagePullSecret, + Value: *pipelinev1.NewStructuredValues("baz"), + }} + req := v1beta1.ResolutionRequestSpec{Params: paramsMissingBundle} + err = resolver.Validate(context.Background(), &req) + if err == nil { + t.Fatalf("expected missing kind err") + } + + paramsMissingName := []pipelinev1.Param{{ + Name: bundleresolution.ParamKind, + Value: *pipelinev1.NewStructuredValues("task"), + }, { + Name: bundleresolution.ParamBundle, + Value: *pipelinev1.NewStructuredValues("bar"), + }, { + Name: bundleresolution.ParamImagePullSecret, + Value: *pipelinev1.NewStructuredValues("baz"), + }} + req = v1beta1.ResolutionRequestSpec{Params: paramsMissingName} + err = resolver.Validate(context.Background(), &req) + if err == nil { + t.Fatalf("expected missing name err") + } +} + +func TestResolveDisabled(t *testing.T) { + resolver := bundle.Resolver{} + + var err error + + params := []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.ParamImagePullSecret, + Value: *pipelinev1.NewStructuredValues("baz"), + }} + req := v1beta1.ResolutionRequestSpec{Params: params} + _, err = resolver.Resolve(resolverDisabledContext(), &req) + if err == nil { + t.Fatalf("expected disabled err") + } + + if d := cmp.Diff(disabledError, err.Error()); d != "" { + t.Errorf("unexpected error: %s", diff.PrintWantGot(d)) + } +} + +func TestResolve_KeyChainError(t *testing.T) { + resolver := &bundle.Resolver{} + params := ¶ms{ + bundle: "foo", + name: "example-task", + kind: "task", + secret: "bar", + } + + ctx, _ := ttesting.SetupFakeContext(t) + request := createRequest(params) + + d := test.Data{ + ResolutionRequests: []*v1beta1.ResolutionRequest{request}, + ConfigMaps: []*corev1.ConfigMap{{ + ObjectMeta: metav1.ObjectMeta{ + Name: bundleresolution.ConfigMapName, + Namespace: resolverconfig.ResolversNamespace(system.Namespace()), + }, + Data: map[string]string{ + bundleresolution.ConfigKind: "task", + }, + }}, + } + + testAssets, cancel := frtesting.GetResolverFrameworkController(ctx, t, d, resolver) + defer cancel() + + expectedErr := apierrors.NewBadRequest("bad request") + // return error when getting secrets from kube client + testAssets.Clients.Kube.Fake.PrependReactor("get", "secrets", func(action ktesting.Action) (bool, runtime.Object, error) { + return true, nil, expectedErr + }) + + err := testAssets.Controller.Reconciler.Reconcile(testAssets.Ctx, strings.Join([]string{request.Namespace, request.Name}, "/")) + if err == nil { + t.Fatalf("expected to get error but got nothing") + } + + if !errors.Is(err, expectedErr) { + t.Fatalf("expected to get error %v, but got %v", expectedErr, err) + } +} + +type params struct { + secret string + bundle string + name string + kind string +} + +func TestResolve(t *testing.T) { + // example task resource + exampleTask := &pipelinev1beta1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example-task", + Namespace: "task-ns", + ResourceVersion: "00002", + }, + TypeMeta: metav1.TypeMeta{ + Kind: string(pipelinev1beta1.NamespacedTaskKind), + APIVersion: "tekton.dev/v1beta1", + }, + Spec: pipelinev1beta1.TaskSpec{ + Steps: []pipelinev1beta1.Step{{ + Name: "some-step", + Image: "some-image", + Command: []string{"something"}, + }}, + }, + } + taskAsYAML, err := yaml.Marshal(exampleTask) + if err != nil { + t.Fatalf("couldn't marshal task: %v", err) + } + + // example pipeline resource + examplePipeline := &pipelinev1beta1.Pipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example-pipeline", + Namespace: "pipeline-ns", + ResourceVersion: "00001", + }, + TypeMeta: metav1.TypeMeta{ + Kind: "Pipeline", + APIVersion: "tekton.dev/v1beta1", + }, + Spec: pipelinev1beta1.PipelineSpec{ + Tasks: []pipelinev1beta1.PipelineTask{{ + Name: "some-pipeline-task", + TaskRef: &pipelinev1beta1.TaskRef{ + Name: "some-task", + Kind: pipelinev1beta1.NamespacedTaskKind, + }, + }}, + }, + } + pipelineAsYAML, err := yaml.Marshal(examplePipeline) + if err != nil { + t.Fatalf("couldn't marshal pipeline: %v", err) + } + + // too many objects in bundle resolver test + var tooManyObjs []runtime.Object + for i := 0; i <= bundleresolution.MaximumBundleObjects; i++ { + name := fmt.Sprintf("%d-task", i) + obj := pipelinev1beta1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: name, + }, + TypeMeta: metav1.TypeMeta{ + APIVersion: "tekton.dev/v1beta1", + Kind: "Task", + }, + } + tooManyObjs = append(tooManyObjs, &obj) + } + + // Set up a fake registry to push an image to. + s := httptest.NewServer(registry.New()) + defer s.Close() + u, err := url.Parse(s.URL) + if err != nil { + t.Fatal(err) + } + r := fmt.Sprintf("%s/%s", u.Host, "testbundleresolver") + testImages := map[string]*imageRef{ + "single-task": pushToRegistry(t, r, "single-task", []runtime.Object{exampleTask}, test.DefaultObjectAnnotationMapper), + "single-pipeline": pushToRegistry(t, r, "single-pipeline", []runtime.Object{examplePipeline}, test.DefaultObjectAnnotationMapper), + "multiple-resources": pushToRegistry(t, r, "multiple-resources", []runtime.Object{exampleTask, examplePipeline}, test.DefaultObjectAnnotationMapper), + "too-many-objs": pushToRegistry(t, r, "too-many-objs", tooManyObjs, asIsMapper), + "single-task-no-version": pushToRegistry(t, r, "single-task-no-version", []runtime.Object{&pipelinev1beta1.Task{TypeMeta: metav1.TypeMeta{Kind: "task"}, ObjectMeta: metav1.ObjectMeta{Name: "foo"}}}, asIsMapper), + "single-task-no-kind": pushToRegistry(t, r, "single-task-no-kind", []runtime.Object{&pipelinev1beta1.Task{TypeMeta: metav1.TypeMeta{APIVersion: "tekton.dev/v1beta1"}, ObjectMeta: metav1.ObjectMeta{Name: "foo"}}}, asIsMapper), + "single-task-no-name": pushToRegistry(t, r, "single-task-no-name", []runtime.Object{&pipelinev1beta1.Task{TypeMeta: metav1.TypeMeta{APIVersion: "tekton.dev/v1beta1", Kind: "task"}}}, asIsMapper), + "single-task-kind-incorrect-form": pushToRegistry(t, r, "single-task-kind-incorrect-form", []runtime.Object{&pipelinev1beta1.Task{TypeMeta: metav1.TypeMeta{APIVersion: "tekton.dev/v1beta1", Kind: "Task"}, ObjectMeta: metav1.ObjectMeta{Name: "foo"}}}, asIsMapper), + } + + testcases := []struct { + name string + args *params + imageName string + kindInBundle string + expectedStatus *v1beta1.ResolutionRequestStatus + expectedErrMessage string + }{ + { + name: "single task: digest is included in the bundle parameter", + args: ¶ms{ + bundle: fmt.Sprintf("%s@%s:%s", testImages["single-task"].uri, testImages["single-task"].algo, testImages["single-task"].hex), + name: "example-task", + kind: "task", + }, + imageName: "single-task", + expectedStatus: resolution.CreateResolutionRequestStatusWithData(taskAsYAML), + }, { + name: "single task: param kind is capitalized, but kind in bundle is not", + args: ¶ms{ + bundle: fmt.Sprintf("%s@%s:%s", testImages["single-task"].uri, testImages["single-task"].algo, testImages["single-task"].hex), + name: "example-task", + kind: "Task", + }, + kindInBundle: "task", + imageName: "single-task", + expectedStatus: resolution.CreateResolutionRequestStatusWithData(taskAsYAML), + }, { + name: "single task: tag is included in the bundle parameter", + args: ¶ms{ + bundle: testImages["single-task"].uri + ":latest", + name: "example-task", + kind: "task", + }, + imageName: "single-task", + expectedStatus: resolution.CreateResolutionRequestStatusWithData(taskAsYAML), + }, { + name: "single task: using default kind value from configmap", + args: ¶ms{ + bundle: testImages["single-task"].uri + ":latest", + name: "example-task", + }, + imageName: "single-task", + expectedStatus: resolution.CreateResolutionRequestStatusWithData(taskAsYAML), + }, { + name: "single pipeline", + args: ¶ms{ + bundle: testImages["single-pipeline"].uri + ":latest", + name: "example-pipeline", + kind: "pipeline", + }, + imageName: "single-pipeline", + expectedStatus: resolution.CreateResolutionRequestStatusWithData(pipelineAsYAML), + }, { + name: "multiple resources: an image has both task and pipeline resource", + args: ¶ms{ + bundle: testImages["multiple-resources"].uri + ":latest", + name: "example-pipeline", + kind: "pipeline", + }, + imageName: "multiple-resources", + expectedStatus: resolution.CreateResolutionRequestStatusWithData(pipelineAsYAML), + }, { + name: "too many objects in an image", + args: ¶ms{ + bundle: testImages["too-many-objs"].uri + ":latest", + name: "2-task", + kind: "task", + }, + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErrMessage: fmt.Sprintf("contained more than the maximum %d allow objects", bundleresolution.MaximumBundleObjects), + }, { + name: "single task no version", + args: ¶ms{ + bundle: testImages["single-task-no-version"].uri + ":latest", + name: "foo", + kind: "task", + }, + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErrMessage: fmt.Sprintf("the layer 0 does not contain a %s annotation", bundleresolution.BundleAnnotationAPIVersion), + }, { + name: "single task no kind", + args: ¶ms{ + bundle: testImages["single-task-no-kind"].uri + ":latest", + name: "foo", + kind: "task", + }, + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErrMessage: fmt.Sprintf("the layer 0 does not contain a %s annotation", bundleresolution.BundleAnnotationKind), + }, { + name: "single task no name", + args: ¶ms{ + bundle: testImages["single-task-no-name"].uri + ":latest", + name: "foo", + kind: "task", + }, + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErrMessage: fmt.Sprintf("the layer 0 does not contain a %s annotation", bundleresolution.BundleAnnotationName), + }, { + name: "single task kind incorrect form", + args: ¶ms{ + bundle: testImages["single-task-kind-incorrect-form"].uri + ":latest", + name: "foo", + kind: "task", + }, + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErrMessage: fmt.Sprintf("the layer 0 the annotation %s must be lowercased and singular, found %s", bundleresolution.BundleAnnotationKind, "Task"), + }, + } + + resolver := &bundle.Resolver{} + confMap := map[string]string{ + bundleresolution.ConfigKind: "task", + } + + for _, tc := range testcases { + t.Run(tc.name, func(t *testing.T) { + ctx, _ := ttesting.SetupFakeContext(t) + + request := createRequest(tc.args) + + d := test.Data{ + ResolutionRequests: []*v1beta1.ResolutionRequest{request}, + ConfigMaps: []*corev1.ConfigMap{{ + ObjectMeta: metav1.ObjectMeta{ + Name: bundleresolution.ConfigMapName, + Namespace: resolverconfig.ResolversNamespace(system.Namespace()), + }, + Data: confMap, + }, { + ObjectMeta: metav1.ObjectMeta{ + Namespace: resolverconfig.ResolversNamespace(system.Namespace()), + Name: resolverconfig.GetFeatureFlagsConfigName(), + }, + Data: map[string]string{ + "enable-bundles-resolver": "true", + }, + }}, + } + var expectedStatus *v1beta1.ResolutionRequestStatus + var expectedError error + if tc.expectedStatus != nil { + expectedStatus = tc.expectedStatus.DeepCopy() + if tc.expectedErrMessage == "" { + if expectedStatus.Annotations == nil { + expectedStatus.Annotations = make(map[string]string) + } + + switch { + case tc.kindInBundle != "": + expectedStatus.Annotations[bundleresolution.ResolverAnnotationKind] = tc.kindInBundle + case tc.args.kind != "": + expectedStatus.Annotations[bundleresolution.ResolverAnnotationKind] = tc.args.kind + default: + expectedStatus.Annotations[bundleresolution.ResolverAnnotationKind] = "task" + } + + expectedStatus.Annotations[bundleresolution.ResolverAnnotationName] = tc.args.name + expectedStatus.Annotations[bundleresolution.ResolverAnnotationAPIVersion] = "v1beta1" + + expectedStatus.RefSource = &pipelinev1.RefSource{ + URI: testImages[tc.imageName].uri, + Digest: map[string]string{ + testImages[tc.imageName].algo: testImages[tc.imageName].hex, + }, + EntryPoint: tc.args.name, + } + expectedStatus.Source = expectedStatus.RefSource + } else { + expectedError = createError(tc.args.bundle, tc.expectedErrMessage) + expectedStatus.Status.Conditions[0].Message = expectedError.Error() + } + } + + frtesting.RunResolverReconcileTest(ctx, t, d, resolver, request, expectedStatus, expectedError) + }) + } +} + +func createRequest(p *params) *v1beta1.ResolutionRequest { + rr := &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: bundle.LabelValueBundleResolverType, + }, + }, + Spec: v1beta1.ResolutionRequestSpec{ + Params: []pipelinev1.Param{{ + Name: bundleresolution.ParamBundle, + Value: *pipelinev1.NewStructuredValues(p.bundle), + }, { + Name: bundleresolution.ParamName, + Value: *pipelinev1.NewStructuredValues(p.name), + }, { + Name: bundleresolution.ParamKind, + Value: *pipelinev1.NewStructuredValues(p.kind), + }, { + Name: bundleresolution.ParamImagePullSecret, + Value: *pipelinev1.NewStructuredValues(p.secret), + }}, + }, + } + return rr +} + +func createError(image, msg string) error { + return &resolutioncommon.GetResourceError{ + ResolverName: bundle.BundleResolverName, + Key: "foo/rr", + Original: fmt.Errorf("invalid tekton bundle %s, error: %s", image, msg), + } +} + +func asIsMapper(obj runtime.Object) map[string]string { + annotations := map[string]string{} + if test.GetObjectName(obj) != "" { + annotations[bundleresolution.BundleAnnotationName] = test.GetObjectName(obj) + } + + if obj.GetObjectKind().GroupVersionKind().Kind != "" { + annotations[bundleresolution.BundleAnnotationKind] = obj.GetObjectKind().GroupVersionKind().Kind + } + if obj.GetObjectKind().GroupVersionKind().Version != "" { + annotations[bundleresolution.BundleAnnotationAPIVersion] = obj.GetObjectKind().GroupVersionKind().Version + } + return annotations +} + +func resolverDisabledContext() context.Context { + return frameworktesting.ContextWithBundlesResolverDisabled(context.Background()) +} + +type imageRef struct { + // uri is the image repositry identifier i.e. "gcr.io/tekton-releases/catalog/upstream/golang-build" + uri string + // algo is the algorithm portion of a particular image digest i.e. "sha256". + algo string + // hex is hex encoded portion of a particular image digest i.e. "23293df97dc11957ec36a88c80101bb554039a76e8992a435112eea8283b30d4". + hex string +} + +// pushToRegistry pushes an image to the registry and returns an imageRef. +// It accepts a registry address, image name, the data and an ObjectAnnotationMapper +// to map an object to the annotations for it. +// NOTE: Every image pushed to the registry has a default tag named "latest". +func pushToRegistry(t *testing.T, registry, imageName string, data []runtime.Object, mapper test.ObjectAnnotationMapper) *imageRef { + t.Helper() + ref, err := test.CreateImageWithAnnotations(fmt.Sprintf("%s/%s:latest", registry, imageName), mapper, data...) + if err != nil { + t.Fatalf("couldn't push the image: %v", err) + } + + refSplit := strings.Split(ref, "@") + uri, digest := refSplit[0], refSplit[1] + digSplits := strings.Split(digest, ":") + algo, hex := digSplits[0], digSplits[1] + + return &imageRef{ + uri: uri, + algo: algo, + hex: hex, + } +} diff --git a/pkg/remoteresolution/resolver/cluster/resolver.go b/pkg/remoteresolution/resolver/cluster/resolver.go new file mode 100644 index 00000000000..7c1e9072334 --- /dev/null +++ b/pkg/remoteresolution/resolver/cluster/resolver.go @@ -0,0 +1,87 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package cluster + +import ( + "context" + + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + clientset "github.com/tektoncd/pipeline/pkg/client/clientset/versioned" + pipelineclient "github.com/tektoncd/pipeline/pkg/client/injection/client" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" + resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + "github.com/tektoncd/pipeline/pkg/resolution/resolver/cluster" + resolutionframework "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" +) + +const ( + // LabelValueClusterResolverType is the value to use for the + // resolution.tekton.dev/type label on resource requests + LabelValueClusterResolverType string = "cluster" + + // ClusterResolverName is the name that the cluster resolver should be + // associated with + ClusterResolverName string = "Cluster" + + configMapName = "cluster-resolver-config" +) + +var _ framework.Resolver = &Resolver{} + +// ResolverV2 implements a framework.Resolver that can fetch resources from other namespaces. +type Resolver struct { + pipelineClientSet clientset.Interface +} + +// Initialize performs any setup required by the cluster resolver. +func (r *Resolver) Initialize(ctx context.Context) error { + r.pipelineClientSet = pipelineclient.Get(ctx) + return nil +} + +// GetName returns the string name that the cluster resolver should be +// associated with. +func (r *Resolver) GetName(_ context.Context) string { + return ClusterResolverName +} + +// GetSelector returns the labels that resource requests are required to have for +// the cluster resolver to process them. +func (r *Resolver) GetSelector(_ context.Context) map[string]string { + return map[string]string{ + resolutioncommon.LabelKeyResolverType: LabelValueClusterResolverType, + } +} + +// Validate returns an error if the given parameter map is not +// valid for a resource request targeting the cluster resolver. +func (r *Resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestSpec) error { + return cluster.ValidateParams(ctx, req.Params) +} + +// Resolve performs the work of fetching a resource from a namespace with the given +// parameters. +func (r *Resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (resolutionframework.ResolvedResource, error) { + return cluster.ResolveFromParams(ctx, req.Params, r.pipelineClientSet) +} + +var _ resolutionframework.ConfigWatcher = &Resolver{} + +// GetConfigName returns the name of the cluster resolver's configmap. +func (r *Resolver) GetConfigName(context.Context) string { + return configMapName +} diff --git a/pkg/remoteresolution/resolver/cluster/resolver_test.go b/pkg/remoteresolution/resolver/cluster/resolver_test.go new file mode 100644 index 00000000000..feecae799c7 --- /dev/null +++ b/pkg/remoteresolution/resolver/cluster/resolver_test.go @@ -0,0 +1,507 @@ +/* + Copyright 2024 The Tekton Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. + +*/ + +package cluster_test + +import ( + "context" + "encoding/base64" + "encoding/hex" + "errors" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + resolverconfig "github.com/tektoncd/pipeline/pkg/apis/config/resolver" + pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/internal/resolution" + ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" + cluster "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/cluster" + frtesting "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework/testing" + resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + clusterresolution "github.com/tektoncd/pipeline/pkg/resolution/resolver/cluster" + "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" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + duckv1 "knative.dev/pkg/apis/duck/v1" + "knative.dev/pkg/system" + _ "knative.dev/pkg/system/testing" + "sigs.k8s.io/yaml" +) + +const ( + disabledError = "cannot handle resolution request, enable-cluster-resolver feature flag not true" +) + +func TestGetSelector(t *testing.T) { + resolver := cluster.Resolver{} + sel := resolver.GetSelector(context.Background()) + if typ, has := sel[resolutioncommon.LabelKeyResolverType]; !has { + t.Fatalf("unexpected selector: %v", sel) + } else if typ != cluster.LabelValueClusterResolverType { + t.Fatalf("unexpected type: %q", typ) + } +} + +func TestValidate(t *testing.T) { + resolver := cluster.Resolver{} + + params := []pipelinev1.Param{{ + Name: clusterresolution.KindParam, + Value: *pipelinev1.NewStructuredValues("task"), + }, { + Name: clusterresolution.NamespaceParam, + Value: *pipelinev1.NewStructuredValues("foo"), + }, { + Name: clusterresolution.NameParam, + Value: *pipelinev1.NewStructuredValues("baz"), + }} + + ctx := framework.InjectResolverConfigToContext(context.Background(), map[string]string{ + clusterresolution.AllowedNamespacesKey: "foo,bar", + clusterresolution.BlockedNamespacesKey: "abc,def", + }) + + req := v1beta1.ResolutionRequestSpec{Params: params} + if err := resolver.Validate(ctx, &req); err != nil { + t.Fatalf("unexpected error validating params: %v", err) + } +} + +func TestValidateNotEnabled(t *testing.T) { + resolver := cluster.Resolver{} + + var err error + + params := []pipelinev1.Param{{ + Name: clusterresolution.KindParam, + Value: *pipelinev1.NewStructuredValues("task"), + }, { + Name: clusterresolution.NamespaceParam, + Value: *pipelinev1.NewStructuredValues("foo"), + }, { + Name: clusterresolution.NameParam, + Value: *pipelinev1.NewStructuredValues("baz"), + }} + req := v1beta1.ResolutionRequestSpec{Params: params} + err = resolver.Validate(resolverDisabledContext(), &req) + if err == nil { + t.Fatalf("expected disabled err") + } + if d := cmp.Diff(disabledError, err.Error()); d != "" { + t.Errorf("unexpected error: %s", diff.PrintWantGot(d)) + } +} + +func TestValidateFailure(t *testing.T) { + testCases := []struct { + name string + params map[string]string + conf map[string]string + expectedErr string + }{ + { + name: "missing kind", + params: map[string]string{ + clusterresolution.NameParam: "foo", + clusterresolution.NamespaceParam: "bar", + }, + expectedErr: "missing required cluster resolver params: kind", + }, { + name: "invalid kind", + params: map[string]string{ + clusterresolution.KindParam: "banana", + clusterresolution.NamespaceParam: "foo", + clusterresolution.NameParam: "bar", + }, + expectedErr: "unknown or unsupported resource kind 'banana'", + }, { + name: "missing multiple", + params: map[string]string{ + clusterresolution.KindParam: "task", + }, + expectedErr: "missing required cluster resolver params: name, namespace", + }, { + name: "not in allowed namespaces", + params: map[string]string{ + clusterresolution.KindParam: "task", + clusterresolution.NamespaceParam: "foo", + clusterresolution.NameParam: "baz", + }, + conf: map[string]string{ + clusterresolution.AllowedNamespacesKey: "abc,def", + }, + expectedErr: "access to specified namespace foo is not allowed", + }, { + name: "in blocked namespaces", + params: map[string]string{ + clusterresolution.KindParam: "task", + clusterresolution.NamespaceParam: "foo", + clusterresolution.NameParam: "baz", + }, + conf: map[string]string{ + clusterresolution.BlockedNamespacesKey: "foo,bar", + }, + expectedErr: "access to specified namespace foo is blocked", + }, + { + name: "blocked by star", + params: map[string]string{ + clusterresolution.KindParam: "task", + clusterresolution.NamespaceParam: "foo", + clusterresolution.NameParam: "baz", + }, + conf: map[string]string{ + clusterresolution.BlockedNamespacesKey: "*", + }, + expectedErr: "only explicit allowed access to namespaces is allowed", + }, + { + name: "blocked by star but allowed explicitly", + params: map[string]string{ + clusterresolution.KindParam: "task", + clusterresolution.NamespaceParam: "foo", + clusterresolution.NameParam: "baz", + }, + conf: map[string]string{ + clusterresolution.BlockedNamespacesKey: "*", + clusterresolution.AllowedNamespacesKey: "foo", + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + resolver := &cluster.Resolver{} + + ctx := context.Background() + if len(tc.conf) > 0 { + ctx = framework.InjectResolverConfigToContext(ctx, tc.conf) + } + + var asParams []pipelinev1.Param + for k, v := range tc.params { + asParams = append(asParams, pipelinev1.Param{ + Name: k, + Value: *pipelinev1.NewStructuredValues(v), + }) + } + req := v1beta1.ResolutionRequestSpec{Params: asParams} + err := resolver.Validate(ctx, &req) + if tc.expectedErr == "" { + if err != nil { + t.Fatalf("got unexpected error: %v", err) + } + return + } + if err == nil { + t.Fatalf("got no error, but expected: %s", tc.expectedErr) + } + if d := cmp.Diff(tc.expectedErr, err.Error()); d != "" { + t.Errorf("error did not match: %s", diff.PrintWantGot(d)) + } + }) + } +} + +func TestResolve(t *testing.T) { + defaultNS := "pipeline-ns" + + exampleTask := &pipelinev1.Task{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example-task", + Namespace: "task-ns", + ResourceVersion: "00002", + UID: "a123", + }, + TypeMeta: metav1.TypeMeta{ + Kind: string(pipelinev1beta1.NamespacedTaskKind), + APIVersion: "tekton.dev/v1", + }, + Spec: pipelinev1.TaskSpec{ + Steps: []pipelinev1.Step{{ + Name: "some-step", + Image: "some-image", + Command: []string{"something"}, + }}, + }, + } + taskChecksum, err := exampleTask.Checksum() + if err != nil { + t.Fatalf("couldn't checksum task: %v", err) + } + taskAsYAML, err := yaml.Marshal(exampleTask) + if err != nil { + t.Fatalf("couldn't marshal task: %v", err) + } + + examplePipeline := &pipelinev1.Pipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "example-pipeline", + Namespace: defaultNS, + ResourceVersion: "00001", + UID: "b123", + }, + TypeMeta: metav1.TypeMeta{ + Kind: "Pipeline", + APIVersion: "tekton.dev/v1", + }, + Spec: pipelinev1.PipelineSpec{ + Tasks: []pipelinev1.PipelineTask{{ + Name: "some-pipeline-task", + TaskRef: &pipelinev1.TaskRef{ + Name: "some-task", + Kind: pipelinev1.NamespacedTaskKind, + }, + }}, + }, + } + pipelineChecksum, err := examplePipeline.Checksum() + if err != nil { + t.Fatalf("couldn't checksum pipeline: %v", err) + } + pipelineAsYAML, err := yaml.Marshal(examplePipeline) + if err != nil { + t.Fatalf("couldn't marshal pipeline: %v", err) + } + + testCases := []struct { + name string + kind string + resourceName string + namespace string + allowedNamespaces string + blockedNamespaces string + expectedStatus *v1beta1.ResolutionRequestStatus + expectedErr error + }{ + { + name: "successful task", + kind: "task", + resourceName: exampleTask.Name, + namespace: exampleTask.Namespace, + expectedStatus: &v1beta1.ResolutionRequestStatus{ + Status: duckv1.Status{}, + ResolutionRequestStatusFields: v1beta1.ResolutionRequestStatusFields{ + Data: base64.StdEncoding.Strict().EncodeToString(taskAsYAML), + RefSource: &pipelinev1.RefSource{ + URI: "/apis/tekton.dev/v1/namespaces/task-ns/task/example-task@a123", + Digest: map[string]string{ + "sha256": hex.EncodeToString(taskChecksum), + }, + }, + }, + }, + }, { + name: "successful pipeline", + kind: "pipeline", + resourceName: examplePipeline.Name, + namespace: examplePipeline.Namespace, + expectedStatus: &v1beta1.ResolutionRequestStatus{ + Status: duckv1.Status{}, + ResolutionRequestStatusFields: v1beta1.ResolutionRequestStatusFields{ + Data: base64.StdEncoding.Strict().EncodeToString(pipelineAsYAML), + RefSource: &pipelinev1.RefSource{ + URI: "/apis/tekton.dev/v1/namespaces/pipeline-ns/pipeline/example-pipeline@b123", + Digest: map[string]string{ + "sha256": hex.EncodeToString(pipelineChecksum), + }, + }, + }, + }, + }, { + name: "default namespace", + kind: "pipeline", + resourceName: examplePipeline.Name, + expectedStatus: &v1beta1.ResolutionRequestStatus{ + Status: duckv1.Status{}, + ResolutionRequestStatusFields: v1beta1.ResolutionRequestStatusFields{ + Data: base64.StdEncoding.Strict().EncodeToString(pipelineAsYAML), + RefSource: &pipelinev1.RefSource{ + URI: "/apis/tekton.dev/v1/namespaces/pipeline-ns/pipeline/example-pipeline@b123", + Digest: map[string]string{ + "sha256": hex.EncodeToString(pipelineChecksum), + }, + }, + }, + }, + }, { + name: "default kind", + resourceName: exampleTask.Name, + namespace: exampleTask.Namespace, + expectedStatus: &v1beta1.ResolutionRequestStatus{ + Status: duckv1.Status{}, + ResolutionRequestStatusFields: v1beta1.ResolutionRequestStatusFields{ + Data: base64.StdEncoding.Strict().EncodeToString(taskAsYAML), + RefSource: &pipelinev1.RefSource{ + URI: "/apis/tekton.dev/v1/namespaces/task-ns/task/example-task@a123", + Digest: map[string]string{ + "sha256": hex.EncodeToString(taskChecksum), + }, + }, + }, + }, + }, { + name: "no such task", + kind: "task", + resourceName: exampleTask.Name, + namespace: "other-ns", + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErr: &resolutioncommon.GetResourceError{ + ResolverName: cluster.ClusterResolverName, + Key: "foo/rr", + Original: errors.New(`tasks.tekton.dev "example-task" not found`), + }, + }, { + name: "not in allowed namespaces", + kind: "task", + resourceName: exampleTask.Name, + namespace: "other-ns", + allowedNamespaces: "foo,bar", + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErr: &resolutioncommon.InvalidRequestError{ + ResolutionRequestKey: "foo/rr", + Message: "access to specified namespace other-ns is not allowed", + }, + }, { + name: "in blocked namespaces", + kind: "task", + resourceName: exampleTask.Name, + namespace: "other-ns", + blockedNamespaces: "foo,other-ns,bar", + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErr: &resolutioncommon.InvalidRequestError{ + ResolutionRequestKey: "foo/rr", + Message: "access to specified namespace other-ns is blocked", + }, + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ctx, _ := ttesting.SetupFakeContext(t) + + request := createRequest(tc.kind, tc.resourceName, tc.namespace) + + confMap := map[string]string{ + clusterresolution.DefaultKindKey: "task", + clusterresolution.DefaultNamespaceKey: defaultNS, + } + if tc.allowedNamespaces != "" { + confMap[clusterresolution.AllowedNamespacesKey] = tc.allowedNamespaces + } + if tc.blockedNamespaces != "" { + confMap[clusterresolution.BlockedNamespacesKey] = tc.blockedNamespaces + } + + d := test.Data{ + ConfigMaps: []*corev1.ConfigMap{{ + ObjectMeta: metav1.ObjectMeta{ + Name: "cluster-resolver-config", + Namespace: resolverconfig.ResolversNamespace(system.Namespace()), + }, + Data: confMap, + }, { + ObjectMeta: metav1.ObjectMeta{ + Namespace: resolverconfig.ResolversNamespace(system.Namespace()), + Name: resolverconfig.GetFeatureFlagsConfigName(), + }, + Data: map[string]string{ + "enable-cluster-resolver": "true", + }, + }}, + Pipelines: []*pipelinev1.Pipeline{examplePipeline}, + ResolutionRequests: []*v1beta1.ResolutionRequest{request}, + Tasks: []*pipelinev1.Task{exampleTask}, + } + + resolver := &cluster.Resolver{} + + var expectedStatus *v1beta1.ResolutionRequestStatus + if tc.expectedStatus != nil { + expectedStatus = tc.expectedStatus.DeepCopy() + + if tc.expectedErr == nil { + reqParams := make(map[string]pipelinev1.ParamValue) + for _, p := range request.Spec.Params { + reqParams[p.Name] = p.Value + } + if expectedStatus.Annotations == nil { + expectedStatus.Annotations = make(map[string]string) + } + expectedStatus.Annotations[clusterresolution.ResourceNameAnnotation] = reqParams[clusterresolution.NameParam].StringVal + if reqParams[clusterresolution.NamespaceParam].StringVal != "" { + expectedStatus.Annotations[clusterresolution.ResourceNamespaceAnnotation] = reqParams[clusterresolution.NamespaceParam].StringVal + } else { + expectedStatus.Annotations[clusterresolution.ResourceNamespaceAnnotation] = defaultNS + } + } else { + expectedStatus.Status.Conditions[0].Message = tc.expectedErr.Error() + } + expectedStatus.Source = expectedStatus.RefSource + } + + frtesting.RunResolverReconcileTest(ctx, t, d, resolver, request, expectedStatus, tc.expectedErr) + }) + } +} + +func createRequest(kind, name, namespace string) *v1beta1.ResolutionRequest { + rr := &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: cluster.LabelValueClusterResolverType, + }, + }, + Spec: v1beta1.ResolutionRequestSpec{ + Params: []pipelinev1.Param{{ + Name: clusterresolution.NameParam, + Value: *pipelinev1.NewStructuredValues(name), + }}, + }, + } + if kind != "" { + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: clusterresolution.KindParam, + Value: *pipelinev1.NewStructuredValues(kind), + }) + } + if namespace != "" { + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: clusterresolution.NamespaceParam, + Value: *pipelinev1.NewStructuredValues(namespace), + }) + } + + return rr +} + +func resolverDisabledContext() context.Context { + return frameworktesting.ContextWithClusterResolverDisabled(context.Background()) +} diff --git a/pkg/remoteresolution/resolver/doc.go b/pkg/remoteresolution/resolver/doc.go new file mode 100644 index 00000000000..784827d34fd --- /dev/null +++ b/pkg/remoteresolution/resolver/doc.go @@ -0,0 +1,25 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package resolver contains the upgraded remote resolution framework. +It contains the upgraded framework and the built-in resolves. +It is equivalent to `pkg/resolution/resolver`. +This was necessary to ensure backwards compatibility with the existing framework. + +This package is subject to further refactoring and changes. +*/ +package resolver diff --git a/pkg/remoteresolution/resolver/framework/controller.go b/pkg/remoteresolution/resolver/framework/controller.go new file mode 100644 index 00000000000..665ecd89e93 --- /dev/null +++ b/pkg/remoteresolution/resolver/framework/controller.go @@ -0,0 +1,124 @@ +/* +Copyright 2022 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package framework + +import ( + "context" + "strings" + + rrclient "github.com/tektoncd/pipeline/pkg/client/resolution/injection/client" + rrinformer "github.com/tektoncd/pipeline/pkg/client/resolution/injection/informers/resolution/v1beta1/resolutionrequest" + framework "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" + "k8s.io/client-go/tools/cache" + "k8s.io/utils/clock" + kubeclient "knative.dev/pkg/client/injection/kube/client" + "knative.dev/pkg/configmap" + "knative.dev/pkg/controller" + "knative.dev/pkg/logging" +) + +// ReconcilerModifier is a func that can access and modify a reconciler +// in the moments before a resolver is started. It allows for +// things like injecting a test clock. +type ReconcilerModifier = func(reconciler *Reconciler) + +// NewController returns a knative controller for a Tekton Resolver. +// This sets up a lot of the boilerplate that individual resolvers +// shouldn't need to be concerned with since it's common to all of them. +func NewController(ctx context.Context, resolver Resolver, modifiers ...ReconcilerModifier) func(context.Context, configmap.Watcher) *controller.Impl { + if err := framework.ValidateResolver(ctx, resolver.GetSelector(ctx)); err != nil { + panic(err.Error()) + } + return func(ctx context.Context, cmw configmap.Watcher) *controller.Impl { + logger := logging.FromContext(ctx) + kubeclientset := kubeclient.Get(ctx) + rrclientset := rrclient.Get(ctx) + rrInformer := rrinformer.Get(ctx) + + if err := resolver.Initialize(ctx); err != nil { + panic(err.Error()) + } + + r := &Reconciler{ + LeaderAwareFuncs: framework.LeaderAwareFuncs(rrInformer.Lister()), + kubeClientSet: kubeclientset, + resolutionRequestLister: rrInformer.Lister(), + resolutionRequestClientSet: rrclientset, + resolver: resolver, + } + + watchConfigChanges(ctx, r, cmw) + + // TODO(sbwsg): Do better sanitize. + resolverName := resolver.GetName(ctx) + resolverName = strings.ReplaceAll(resolverName, "/", "") + resolverName = strings.ReplaceAll(resolverName, " ", "") + + applyModifiersAndDefaults(ctx, r, modifiers) + + impl := controller.NewContext(ctx, r, controller.ControllerOptions{ + WorkQueueName: "TektonResolverFramework." + resolverName, + Logger: logger, + }) + + _, err := rrInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ + FilterFunc: framework.FilterResolutionRequestsBySelector(resolver.GetSelector(ctx)), + Handler: cache.ResourceEventHandlerFuncs{ + AddFunc: impl.Enqueue, + UpdateFunc: func(oldObj, newObj interface{}) { + impl.Enqueue(newObj) + }, + // TODO(sbwsg): should we deliver delete events + // to the resolver? + // DeleteFunc: impl.Enqueue, + }, + }) + if err != nil { + logging.FromContext(ctx).Panicf("Couldn't register ResolutionRequest informer event handler: %w", err) + } + + return impl + } +} + +// watchConfigChanges binds a framework.Resolver to updates on its +// configmap, using knative's configmap helpers. This is only done if +// the resolver implements the framework.ConfigWatcher interface. +func watchConfigChanges(ctx context.Context, reconciler *Reconciler, cmw configmap.Watcher) { + if configWatcher, ok := reconciler.resolver.(framework.ConfigWatcher); ok { + logger := logging.FromContext(ctx) + resolverConfigName := configWatcher.GetConfigName(ctx) + if resolverConfigName == "" { + panic("resolver returned empty config name") + } + reconciler.configStore = framework.NewConfigStore(resolverConfigName, logger) + reconciler.configStore.WatchConfigs(cmw) + } +} + +// applyModifiersAndDefaults applies the given modifiers to +// a reconciler and, after doing so, sets any default values for things +// that weren't set by a modifier. +func applyModifiersAndDefaults(ctx context.Context, r *Reconciler, modifiers []ReconcilerModifier) { + for _, mod := range modifiers { + mod(r) + } + + if r.Clock == nil { + r.Clock = clock.RealClock{} + } +} diff --git a/pkg/remoteresolution/resolver/framework/doc.go b/pkg/remoteresolution/resolver/framework/doc.go new file mode 100644 index 00000000000..765551cab71 --- /dev/null +++ b/pkg/remoteresolution/resolver/framework/doc.go @@ -0,0 +1,24 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package framework contains the upgraded remote resolution framework. +It is equivalent to `pkg/resolution/resolver/framework`. +This was necessary to ensure backwards compatibility with the existing framework. + +This package is subject to further refactoring and changes. +*/ +package framework diff --git a/pkg/remoteresolution/resolver/framework/fakeresolver.go b/pkg/remoteresolution/resolver/framework/fakeresolver.go new file mode 100644 index 00000000000..995ead2e19e --- /dev/null +++ b/pkg/remoteresolution/resolver/framework/fakeresolver.go @@ -0,0 +1,73 @@ +/* + Copyright 2022 The Tekton Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package framework + +import ( + "context" + "time" + + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" +) + +var _ Resolver = &FakeResolver{} + +// FakeResolver implements a framework.Resolver that can fetch pre-configured strings based on a parameter value, or return +// resolution attempts with a configured error. +type FakeResolver framework.FakeResolver + +// Initialize performs any setup required by the fake resolver. +func (r *FakeResolver) Initialize(ctx context.Context) error { + if r.ForParam == nil { + r.ForParam = make(map[string]*framework.FakeResolvedResource) + } + return nil +} + +// GetName returns the string name that the fake resolver should be +// associated with. +func (r *FakeResolver) GetName(_ context.Context) string { + return framework.FakeResolverName +} + +// GetSelector returns the labels that resource requests are required to have for +// the fake resolver to process them. +func (r *FakeResolver) GetSelector(_ context.Context) map[string]string { + return map[string]string{ + resolutioncommon.LabelKeyResolverType: framework.LabelValueFakeResolverType, + } +} + +// Validate returns an error if the given parameter map is not +// valid for a resource request targeting the fake resolver. +func (r *FakeResolver) Validate(_ context.Context, req *v1beta1.ResolutionRequestSpec) error { + return framework.ValidateParams(req.Params) +} + +// Resolve performs the work of fetching a file from the fake resolver given a map of +// parameters. +func (r *FakeResolver) Resolve(_ context.Context, req *v1beta1.ResolutionRequestSpec) (framework.ResolvedResource, error) { + return framework.Resolve(req.Params, r.ForParam) +} + +var _ framework.TimedResolution = &FakeResolver{} + +// GetResolutionTimeout returns the configured timeout for the reconciler, or the default time.Duration if not configured. +func (r *FakeResolver) GetResolutionTimeout(ctx context.Context, defaultTimeout time.Duration) time.Duration { + return framework.GetResolutionTimeout(r.Timeout, defaultTimeout) +} diff --git a/pkg/remoteresolution/resolver/framework/interface.go b/pkg/remoteresolution/resolver/framework/interface.go new file mode 100644 index 00000000000..53cc9443143 --- /dev/null +++ b/pkg/remoteresolution/resolver/framework/interface.go @@ -0,0 +1,53 @@ +/* +Copyright 2022 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package framework + +import ( + "context" + + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" +) + +// Resolver is the interface to implement for type-specific resource +// resolution. It fetches resources from a given type of remote location +// and returns their content along with any associated annotations. +type Resolver interface { + // Initialize is called at the moment the resolver controller is + // instantiated and is a good place to setup things like + // resource listers. + Initialize(ctx context.Context) error + + // GetName should give back the name of the resolver. E.g. "Git" + GetName(ctx context.Context) string + + // GetSelector returns the labels that are used to direct resolution + // requests to this resolver. + GetSelector(ctx context.Context) map[string]string + + // Validate is given the ressolution request spec + // should return an error if the resolver cannot resolve it. + Validate(ctx context.Context, req *v1beta1.ResolutionRequestSpec) error + + // ResolveRequest receives the resolution request spec + // and returns the resolved data along with any annotations + // to include in the response. If resolution fails then an error + // should be returned instead. If a resolution.Error + // is returned then its Reason and Message are used as part of the + // response to the request. + Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (framework.ResolvedResource, error) +} diff --git a/pkg/remoteresolution/resolver/framework/reconciler.go b/pkg/remoteresolution/resolver/framework/reconciler.go new file mode 100644 index 00000000000..c4fb6177075 --- /dev/null +++ b/pkg/remoteresolution/resolver/framework/reconciler.go @@ -0,0 +1,230 @@ +/* +Copyright 2022 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package framework + +import ( + "context" + "encoding/base64" + "encoding/json" + "errors" + "fmt" + "time" + + pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + rrclient "github.com/tektoncd/pipeline/pkg/client/resolution/clientset/versioned" + rrv1beta1 "github.com/tektoncd/pipeline/pkg/client/resolution/listers/resolution/v1beta1" + resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/kubernetes" + "k8s.io/client-go/tools/cache" + "k8s.io/utils/clock" + "knative.dev/pkg/controller" + "knative.dev/pkg/logging" + "knative.dev/pkg/reconciler" +) + +// defaultMaximumResolutionDuration is the maximum amount of time +// resolution may take. + +// defaultMaximumResolutionDuration is the max time that a call to +// Resolve() may take. It can be overridden by a resolver implementing +// the framework.TimedResolution interface. +const defaultMaximumResolutionDuration = time.Minute + +// statusDataPatch is the json structure that will be PATCHed into +// a ResolutionRequest with its data and annotations once successfully +// resolved. +type statusDataPatch struct { + Annotations map[string]string `json:"annotations"` + Data string `json:"data"` + Source *pipelinev1beta1.ConfigSource `json:"source"` + RefSource *pipelinev1.RefSource `json:"refSource"` +} + +// Reconciler handles ResolutionRequest objects, performs functionality +// common to all resolvers and delegates resolver-specific actions +// to its embedded type-specific Resolver object. +type Reconciler struct { + // Implements reconciler.LeaderAware + reconciler.LeaderAwareFuncs + + // Clock is used by the reconciler to track the passage of time + // and can be overridden for tests. + Clock clock.PassiveClock + + resolver Resolver + kubeClientSet kubernetes.Interface + resolutionRequestLister rrv1beta1.ResolutionRequestLister + resolutionRequestClientSet rrclient.Interface + + configStore *framework.ConfigStore +} + +var _ reconciler.LeaderAware = &Reconciler{} + +// Reconcile receives the string key of a ResolutionRequest object, looks +// it up, checks it for common errors, and then delegates +// resolver-specific functionality to the reconciler's embedded +// type-specific resolver. Any errors that occur during validation or +// resolution are handled by updating or failing the ResolutionRequest. +func (r *Reconciler) Reconcile(ctx context.Context, key string) error { + namespace, name, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + err = &resolutioncommon.InvalidResourceKeyError{Key: key, Original: err} + return controller.NewPermanentError(err) + } + + rr, err := r.resolutionRequestLister.ResolutionRequests(namespace).Get(name) + if err != nil { + err := &resolutioncommon.GetResourceError{ResolverName: "resolutionrequest", Key: key, Original: err} + return controller.NewPermanentError(err) + } + + if rr.IsDone() { + return nil + } + + // Inject request-scoped information into the context, such as + // the namespace that the request originates from and the + // configuration from the configmap this resolver is watching. + ctx = resolutioncommon.InjectRequestNamespace(ctx, namespace) + ctx = resolutioncommon.InjectRequestName(ctx, name) + if r.configStore != nil { + ctx = r.configStore.ToContext(ctx) + } + + return r.resolve(ctx, key, rr) +} + +func (r *Reconciler) resolve(ctx context.Context, key string, rr *v1beta1.ResolutionRequest) error { + errChan := make(chan error) + resourceChan := make(chan framework.ResolvedResource) + + timeoutDuration := defaultMaximumResolutionDuration + if timed, ok := r.resolver.(framework.TimedResolution); ok { + timeoutDuration = timed.GetResolutionTimeout(ctx, defaultMaximumResolutionDuration) + } + + // A new context is created for resolution so that timeouts can + // be enforced without affecting other uses of ctx (e.g. sending + // Updates to ResolutionRequest objects). + resolutionCtx, cancelFn := context.WithTimeout(ctx, timeoutDuration) + defer cancelFn() + + go func() { + validationError := r.resolver.Validate(resolutionCtx, &rr.Spec) + if validationError != nil { + errChan <- &resolutioncommon.InvalidRequestError{ + ResolutionRequestKey: key, + Message: validationError.Error(), + } + return + } + resource, resolveErr := r.resolver.Resolve(resolutionCtx, &rr.Spec) + if resolveErr != nil { + errChan <- &resolutioncommon.GetResourceError{ + ResolverName: r.resolver.GetName(resolutionCtx), + Key: key, + Original: resolveErr, + } + return + } + resourceChan <- resource + }() + + select { + case err := <-errChan: + if err != nil { + return r.OnError(ctx, rr, err) + } + case <-resolutionCtx.Done(): + if err := resolutionCtx.Err(); err != nil { + return r.OnError(ctx, rr, err) + } + case resource := <-resourceChan: + return r.writeResolvedData(ctx, rr, resource) + } + + return errors.New("unknown error") +} + +// OnError is used to handle any situation where a ResolutionRequest has +// reached a terminal situation that cannot be recovered from. +func (r *Reconciler) OnError(ctx context.Context, rr *v1beta1.ResolutionRequest, err error) error { + if rr == nil { + return controller.NewPermanentError(err) + } + if err != nil { + _ = r.MarkFailed(ctx, rr, err) + return controller.NewPermanentError(err) + } + return nil +} + +// MarkFailed updates a ResolutionRequest as having failed. It returns +// errors that occur during the update process or nil if the update +// appeared to succeed. +func (r *Reconciler) MarkFailed(ctx context.Context, rr *v1beta1.ResolutionRequest, resolutionErr error) error { + key := fmt.Sprintf("%s/%s", rr.Namespace, rr.Name) + reason, resolutionErr := resolutioncommon.ReasonError(resolutionErr) + latestGeneration, err := r.resolutionRequestClientSet.ResolutionV1beta1().ResolutionRequests(rr.Namespace).Get(ctx, rr.Name, metav1.GetOptions{}) + if err != nil { + logging.FromContext(ctx).Warnf("error getting latest generation of resolutionrequest %q: %v", key, err) + return err + } + if latestGeneration.IsDone() { + return nil + } + latestGeneration.Status.MarkFailed(reason, resolutionErr.Error()) + _, err = r.resolutionRequestClientSet.ResolutionV1beta1().ResolutionRequests(rr.Namespace).UpdateStatus(ctx, latestGeneration, metav1.UpdateOptions{}) + if err != nil { + logging.FromContext(ctx).Warnf("error marking resolutionrequest %q as failed: %v", key, err) + return err + } + return nil +} + +func (r *Reconciler) writeResolvedData(ctx context.Context, rr *v1beta1.ResolutionRequest, resource framework.ResolvedResource) error { + encodedData := base64.StdEncoding.Strict().EncodeToString(resource.Data()) + patchBytes, err := json.Marshal(map[string]statusDataPatch{ + "status": { + Data: encodedData, + Annotations: resource.Annotations(), + RefSource: resource.RefSource(), + Source: (*pipelinev1beta1.ConfigSource)(resource.RefSource()), + }, + }) + if err != nil { + return r.OnError(ctx, rr, &resolutioncommon.UpdatingRequestError{ + ResolutionRequestKey: fmt.Sprintf("%s/%s", rr.Namespace, rr.Name), + Original: fmt.Errorf("error serializing resource request patch: %w", err), + }) + } + _, err = r.resolutionRequestClientSet.ResolutionV1beta1().ResolutionRequests(rr.Namespace).Patch(ctx, rr.Name, types.MergePatchType, patchBytes, metav1.PatchOptions{}, "status") + if err != nil { + return r.OnError(ctx, rr, &resolutioncommon.UpdatingRequestError{ + ResolutionRequestKey: fmt.Sprintf("%s/%s", rr.Namespace, rr.Name), + Original: err, + }) + } + + return nil +} diff --git a/pkg/remoteresolution/resolver/framework/reconciler_test.go b/pkg/remoteresolution/resolver/framework/reconciler_test.go new file mode 100644 index 00000000000..e72582ca471 --- /dev/null +++ b/pkg/remoteresolution/resolver/framework/reconciler_test.go @@ -0,0 +1,290 @@ +/* + Copyright 2022 The Tekton Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package framework_test + +import ( + "context" + "encoding/base64" + "errors" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" + resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + resolutionframework "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" + "github.com/tektoncd/pipeline/test" + "github.com/tektoncd/pipeline/test/diff" + "github.com/tektoncd/pipeline/test/names" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/tools/record" + clock "k8s.io/utils/clock/testing" + "knative.dev/pkg/apis" + duckv1 "knative.dev/pkg/apis/duck/v1" + cminformer "knative.dev/pkg/configmap/informer" + "knative.dev/pkg/controller" + "knative.dev/pkg/logging" + pkgreconciler "knative.dev/pkg/reconciler" + "knative.dev/pkg/system" + _ "knative.dev/pkg/system/testing" // Setup system.Namespace() +) + +var ( + now = time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC) + testClock = clock.NewFakePassiveClock(now) + ignoreLastTransitionTime = cmpopts.IgnoreFields(apis.Condition{}, "LastTransitionTime.Inner.Time") +) + +func TestReconcile(t *testing.T) { + testCases := []struct { + name string + inputRequest *v1beta1.ResolutionRequest + paramMap map[string]*resolutionframework.FakeResolvedResource + reconcilerTimeout time.Duration + expectedStatus *v1beta1.ResolutionRequestStatus + expectedErr error + }{ + { + name: "unknown value", + inputRequest: &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: resolutionframework.LabelValueFakeResolverType, + }, + }, + Spec: v1beta1.ResolutionRequestSpec{ + Params: []pipelinev1.Param{{ + Name: resolutionframework.FakeParamName, + Value: *pipelinev1.NewStructuredValues("bar"), + }}, + }, + Status: v1beta1.ResolutionRequestStatus{}, + }, + expectedErr: errors.New("error getting \"Fake\" \"foo/rr\": couldn't find resource for param value bar"), + }, { + name: "known value", + inputRequest: &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: resolutionframework.LabelValueFakeResolverType, + }, + }, + Spec: v1beta1.ResolutionRequestSpec{ + Params: []pipelinev1.Param{{ + Name: resolutionframework.FakeParamName, + Value: *pipelinev1.NewStructuredValues("bar"), + }}, + }, + Status: v1beta1.ResolutionRequestStatus{}, + }, + paramMap: map[string]*resolutionframework.FakeResolvedResource{ + "bar": { + Content: "some content", + AnnotationMap: map[string]string{"foo": "bar"}, + ContentSource: &pipelinev1.RefSource{ + URI: "https://abc.com", + Digest: map[string]string{ + "sha1": "xyz", + }, + EntryPoint: "foo/bar", + }, + }, + }, + expectedStatus: &v1beta1.ResolutionRequestStatus{ + Status: duckv1.Status{ + Annotations: map[string]string{ + "foo": "bar", + }, + }, + ResolutionRequestStatusFields: v1beta1.ResolutionRequestStatusFields{ + Data: base64.StdEncoding.Strict().EncodeToString([]byte("some content")), + RefSource: &pipelinev1.RefSource{ + URI: "https://abc.com", + Digest: map[string]string{ + "sha1": "xyz", + }, + EntryPoint: "foo/bar", + }, + Source: &pipelinev1.RefSource{ + URI: "https://abc.com", + Digest: map[string]string{ + "sha1": "xyz", + }, + EntryPoint: "foo/bar", + }, + }, + }, + }, { + name: "error resolving", + inputRequest: &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: resolutionframework.LabelValueFakeResolverType, + }, + }, + Spec: v1beta1.ResolutionRequestSpec{ + Params: []pipelinev1.Param{{ + Name: resolutionframework.FakeParamName, + Value: *pipelinev1.NewStructuredValues("bar"), + }}, + }, + Status: v1beta1.ResolutionRequestStatus{}, + }, + paramMap: map[string]*resolutionframework.FakeResolvedResource{ + "bar": { + ErrorWith: "fake failure", + }, + }, + expectedErr: errors.New(`error getting "Fake" "foo/rr": fake failure`), + }, { + name: "timeout", + inputRequest: &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().Add(-59 * time.Second)}, // 1 second before default timeout + Labels: map[string]string{ + resolutioncommon.LabelKeyResolverType: resolutionframework.LabelValueFakeResolverType, + }, + }, + Spec: v1beta1.ResolutionRequestSpec{ + Params: []pipelinev1.Param{{ + Name: resolutionframework.FakeParamName, + Value: *pipelinev1.NewStructuredValues("bar"), + }}, + }, + Status: v1beta1.ResolutionRequestStatus{}, + }, + paramMap: map[string]*resolutionframework.FakeResolvedResource{ + "bar": { + WaitFor: 1100 * time.Millisecond, + }, + }, + reconcilerTimeout: 1 * time.Second, + expectedErr: errors.New("context deadline exceeded"), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + d := test.Data{ + ResolutionRequests: []*v1beta1.ResolutionRequest{tc.inputRequest}, + } + + fakeResolver := &framework.FakeResolver{ForParam: tc.paramMap} + if tc.reconcilerTimeout > 0 { + fakeResolver.Timeout = tc.reconcilerTimeout + } + + ctx, _ := ttesting.SetupFakeContext(t) + testAssets, cancel := getResolverFrameworkController(ctx, t, d, fakeResolver, setClockOnReconciler) + defer cancel() + + err := testAssets.Controller.Reconciler.Reconcile(testAssets.Ctx, getRequestName(tc.inputRequest)) + if tc.expectedErr != nil { + if err == nil { + t.Fatalf("expected to get error %v, but got nothing", tc.expectedErr) + } + if tc.expectedErr.Error() != err.Error() { + t.Fatalf("expected to get error %v, but got %v", tc.expectedErr, err) + } + } else { + if err != nil { + if ok, _ := controller.IsRequeueKey(err); !ok { + t.Fatalf("did not expect an error, but got %v", err) + } + } + + c := testAssets.Clients.ResolutionRequests.ResolutionV1beta1() + reconciledRR, err := c.ResolutionRequests(tc.inputRequest.Namespace).Get(testAssets.Ctx, tc.inputRequest.Name, metav1.GetOptions{}) + if err != nil { + t.Fatalf("getting updated ResolutionRequest: %v", err) + } + if d := cmp.Diff(*tc.expectedStatus, reconciledRR.Status, ignoreLastTransitionTime); d != "" { + t.Errorf("ResolutionRequest status doesn't match %s", diff.PrintWantGot(d)) + } + } + }) + } +} + +func getResolverFrameworkController(ctx context.Context, t *testing.T, d test.Data, resolver framework.Resolver, modifiers ...framework.ReconcilerModifier) (test.Assets, func()) { + t.Helper() + names.TestingSeed() + + ctx, cancel := context.WithCancel(ctx) + c, informers := test.SeedTestData(t, ctx, d) + configMapWatcher := cminformer.NewInformedWatcher(c.Kube, system.Namespace()) + ctl := framework.NewController(ctx, resolver, modifiers...)(ctx, configMapWatcher) + if err := configMapWatcher.Start(ctx.Done()); err != nil { + t.Fatalf("error starting configmap watcher: %v", err) + } + + if la, ok := ctl.Reconciler.(pkgreconciler.LeaderAware); ok { + _ = la.Promote(pkgreconciler.UniversalBucket(), func(pkgreconciler.Bucket, types.NamespacedName) {}) + } + + return test.Assets{ + Logger: logging.FromContext(ctx), + Controller: ctl, + Clients: c, + Informers: informers, + Recorder: controller.GetEventRecorder(ctx).(*record.FakeRecorder), + Ctx: ctx, + }, cancel +} + +func getRequestName(rr *v1beta1.ResolutionRequest) string { + return strings.Join([]string{rr.Namespace, rr.Name}, "/") +} + +func setClockOnReconciler(r *framework.Reconciler) { + if r.Clock == nil { + r.Clock = testClock + } +} diff --git a/pkg/remoteresolution/resolver/framework/testing/fakecontroller.go b/pkg/remoteresolution/resolver/framework/testing/fakecontroller.go new file mode 100644 index 00000000000..eefee4263da --- /dev/null +++ b/pkg/remoteresolution/resolver/framework/testing/fakecontroller.go @@ -0,0 +1,171 @@ +/* + Copyright 2022 The Tekton Authors + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + See the License for the specific language governing permissions and + limitations under the License. +*/ + +package testing + +import ( + "context" + "encoding/base64" + "strings" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + resolverconfig "github.com/tektoncd/pipeline/pkg/apis/config/resolver" + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" + "github.com/tektoncd/pipeline/test" + "github.com/tektoncd/pipeline/test/diff" + "github.com/tektoncd/pipeline/test/names" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/types" + "k8s.io/client-go/tools/record" + testclock "k8s.io/utils/clock/testing" + "knative.dev/pkg/apis" + cminformer "knative.dev/pkg/configmap/informer" + "knative.dev/pkg/controller" + "knative.dev/pkg/logging" + pkgreconciler "knative.dev/pkg/reconciler" + "knative.dev/pkg/system" +) + +var ( + now = time.Date(2022, time.January, 1, 0, 0, 0, 0, time.UTC) + testClock = testclock.NewFakePassiveClock(now) + ignoreLastTransitionTime = cmpopts.IgnoreFields(apis.Condition{}, "LastTransitionTime.Inner.Time") +) + +// ResolverReconcileTestModifier is a function thaat will be invoked after the test assets and controller have been created +type ResolverReconcileTestModifier = func(resolver framework.Resolver, testAssets test.Assets) + +// RunResolverReconcileTest takes data to seed clients and informers, a Resolver, a ResolutionRequest, and the expected +// ResolutionRequestStatus and error, both of which can be nil. It instantiates a controller for that resolver and +// reconciles the given request. It then checks for the expected error, if any, and compares the resulting status with +// the expected status. +func RunResolverReconcileTest(ctx context.Context, t *testing.T, d test.Data, resolver framework.Resolver, request *v1beta1.ResolutionRequest, + expectedStatus *v1beta1.ResolutionRequestStatus, expectedErr error, resolverModifiers ...ResolverReconcileTestModifier) { + t.Helper() + + testAssets, cancel := GetResolverFrameworkController(ctx, t, d, resolver, setClockOnReconciler) + defer cancel() + + for _, rm := range resolverModifiers { + rm(resolver, testAssets) + } + + err := testAssets.Controller.Reconciler.Reconcile(testAssets.Ctx, getRequestName(request)) //nolint + if expectedErr != nil { + if err == nil { + t.Fatalf("expected to get error: `%v`, but got nothing", expectedErr) + } + if expectedErr.Error() != err.Error() { + t.Fatalf("expected to get error `%v`, but got `%v`", expectedErr, err) + } + } else if err != nil { + if ok, _ := controller.IsRequeueKey(err); !ok { + t.Fatalf("did not expect an error, but got `%v`", err) + } + } + + c := testAssets.Clients.ResolutionRequests.ResolutionV1beta1() + reconciledRR, err := c.ResolutionRequests(request.Namespace).Get(testAssets.Ctx, request.Name, metav1.GetOptions{}) //nolint + if err != nil { + t.Fatalf("getting updated ResolutionRequest: %v", err) + } + if expectedStatus != nil { + if d := cmp.Diff(*expectedStatus, reconciledRR.Status, ignoreLastTransitionTime); d != "" { + t.Errorf("ResolutionRequest status doesn't match %s", diff.PrintWantGot(d)) + if expectedStatus.Data != "" && expectedStatus.Data != reconciledRR.Status.Data { + decodedExpectedData, err := base64.StdEncoding.Strict().DecodeString(expectedStatus.Data) + if err != nil { + t.Errorf("couldn't decode expected data: %v", err) + return + } + decodedGotData, err := base64.StdEncoding.Strict().DecodeString(reconciledRR.Status.Data) + if err != nil { + t.Errorf("couldn't decode reconciled data: %v", err) + return + } + if d := cmp.Diff(decodedExpectedData, decodedGotData); d != "" { + t.Errorf("decoded data did not match expected: %s", diff.PrintWantGot(d)) + } + } + } + } +} + +// GetResolverFrameworkController returns an instance of the resolver framework controller/reconciler using the given resolver, +// seeded with d, where d represents the state of the system (existing resources) needed for the test. +func GetResolverFrameworkController(ctx context.Context, t *testing.T, d test.Data, resolver framework.Resolver, modifiers ...framework.ReconcilerModifier) (test.Assets, func()) { + t.Helper() + names.TestingSeed() + return initializeResolverFrameworkControllerAssets(ctx, t, d, resolver, modifiers...) +} + +func initializeResolverFrameworkControllerAssets(ctx context.Context, t *testing.T, d test.Data, resolver framework.Resolver, modifiers ...framework.ReconcilerModifier) (test.Assets, func()) { + t.Helper() + ctx, cancel := context.WithCancel(ctx) + ensureConfigurationConfigMapsExist(&d) + c, informers := test.SeedTestData(t, ctx, d) + configMapWatcher := cminformer.NewInformedWatcher(c.Kube, resolverconfig.ResolversNamespace(system.Namespace())) + ctl := framework.NewController(ctx, resolver, modifiers...)(ctx, configMapWatcher) + if err := configMapWatcher.Start(ctx.Done()); err != nil { + t.Fatalf("error starting configmap watcher: %v", err) + } + + if la, ok := ctl.Reconciler.(pkgreconciler.LeaderAware); ok { + _ = la.Promote(pkgreconciler.UniversalBucket(), func(pkgreconciler.Bucket, types.NamespacedName) {}) + } + + return test.Assets{ + Logger: logging.FromContext(ctx), + Controller: ctl, + Clients: c, + Informers: informers, + Recorder: controller.GetEventRecorder(ctx).(*record.FakeRecorder), + Ctx: ctx, + }, cancel +} + +func getRequestName(rr *v1beta1.ResolutionRequest) string { + return strings.Join([]string{rr.Namespace, rr.Name}, "/") +} + +func setClockOnReconciler(r *framework.Reconciler) { + if r.Clock == nil { + r.Clock = testClock + } +} + +func ensureConfigurationConfigMapsExist(d *test.Data) { + var featureFlagsExists bool + for _, cm := range d.ConfigMaps { + if cm.Name == resolverconfig.GetFeatureFlagsConfigName() { + featureFlagsExists = true + } + } + if !featureFlagsExists { + d.ConfigMaps = append(d.ConfigMaps, &corev1.ConfigMap{ + ObjectMeta: metav1.ObjectMeta{ + Name: resolverconfig.GetFeatureFlagsConfigName(), + Namespace: resolverconfig.ResolversNamespace(system.Namespace()), + }, + Data: map[string]string{}, + }) + } +} diff --git a/pkg/remoteresolution/resolver/git/resolver.go b/pkg/remoteresolution/resolver/git/resolver.go new file mode 100644 index 00000000000..8aa15b65bd0 --- /dev/null +++ b/pkg/remoteresolution/resolver/git/resolver.go @@ -0,0 +1,145 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package git + +import ( + "context" + "errors" + "time" + + "github.com/jenkins-x/go-scm/scm" + "github.com/jenkins-x/go-scm/scm/factory" + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" + resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + resolutionframework "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" + "github.com/tektoncd/pipeline/pkg/resolution/resolver/git" + "go.uber.org/zap" + "k8s.io/apimachinery/pkg/util/cache" + "k8s.io/client-go/kubernetes" + kubeclient "knative.dev/pkg/client/injection/kube/client" + "knative.dev/pkg/logging" +) + +const ( + disabledError = "cannot handle resolution request, enable-git-resolver feature flag not true" + + // labelValueGitResolverType is the value to use for the + // resolution.tekton.dev/type label on resource requests + labelValueGitResolverType string = "git" + + // gitResolverName is the name that the git resolver should be + // associated with + gitResolverName string = "Git" + + // ConfigMapName is the git resolver's config map + ConfigMapName = "git-resolver-config" + + // cacheSize is the size of the LRU secrets cache + cacheSize = 1024 + // ttl is the time to live for a cache entry + ttl = 5 * time.Minute +) + +var _ framework.Resolver = &Resolver{} + +// Resolver implements a framework.Resolver that can fetch files from git. +type Resolver struct { + kubeClient kubernetes.Interface + logger *zap.SugaredLogger + cache *cache.LRUExpireCache + ttl time.Duration + + // Used in testing + clientFunc func(string, string, string, ...factory.ClientOptionFunc) (*scm.Client, error) +} + +// Initialize performs any setup required by the gitresolver. +func (r *Resolver) Initialize(ctx context.Context) error { + r.kubeClient = kubeclient.Get(ctx) + r.logger = logging.FromContext(ctx) + r.cache = cache.NewLRUExpireCache(cacheSize) + r.ttl = ttl + if r.clientFunc == nil { + r.clientFunc = factory.NewClient + } + return nil +} + +// GetName returns the string name that the gitresolver should be +// associated with. +func (r *Resolver) GetName(_ context.Context) string { + return gitResolverName +} + +// GetSelector returns the labels that resource requests are required to have for +// the gitresolver to process them. +func (r *Resolver) GetSelector(_ context.Context) map[string]string { + return map[string]string{ + resolutioncommon.LabelKeyResolverType: labelValueGitResolverType, + } +} + +// ValidateParams returns an error if the given parameter map is not +// valid for a resource request targeting the gitresolver. +func (r *Resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestSpec) error { + return git.ValidateParams(ctx, req.Params) +} + +// Resolve performs the work of fetching a file from git given a map of +// parameters. +func (r *Resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (resolutionframework.ResolvedResource, error) { + origParams := req.Params + + if git.IsDisabled(ctx) { + return nil, errors.New(disabledError) + } + + params, err := git.PopulateDefaultParams(ctx, origParams) + if err != nil { + return nil, err + } + + if params[git.UrlParam] != "" { + return git.ResolveAnonymousGit(ctx, params) + } + + return git.ResolveAPIGit(ctx, params, r.kubeClient, r.logger, r.cache, r.ttl, r.clientFunc) +} + +var _ resolutionframework.ConfigWatcher = &Resolver{} + +// GetConfigName returns the name of the git resolver's configmap. +func (r *Resolver) GetConfigName(context.Context) string { + return ConfigMapName +} + +var _ resolutionframework.TimedResolution = &Resolver{} + +// GetResolutionTimeout returns a time.Duration for the amount of time a +// single git fetch may take. This can be configured with the +// fetch-timeout field in the git-resolver-config configmap. +func (r *Resolver) GetResolutionTimeout(ctx context.Context, defaultTimeout time.Duration) time.Duration { + conf := resolutionframework.GetResolverConfigFromContext(ctx) + if timeoutString, ok := conf[git.DefaultTimeoutKey]; ok { + timeout, err := time.ParseDuration(timeoutString) + if err == nil { + return timeout + } + } + return defaultTimeout +} diff --git a/pkg/remoteresolution/resolver/git/resolver_test.go b/pkg/remoteresolution/resolver/git/resolver_test.go new file mode 100644 index 00000000000..18c3e629e70 --- /dev/null +++ b/pkg/remoteresolution/resolver/git/resolver_test.go @@ -0,0 +1,908 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package git + +import ( + "context" + "encoding/base64" + "errors" + "fmt" + "os" + "path/filepath" + "testing" + "time" + + "github.com/go-git/go-git/v5" + "github.com/go-git/go-git/v5/plumbing" + "github.com/go-git/go-git/v5/plumbing/object" + "github.com/google/go-cmp/cmp" + "github.com/jenkins-x/go-scm/scm" + "github.com/jenkins-x/go-scm/scm/driver/fake" + "github.com/jenkins-x/go-scm/scm/factory" + resolverconfig "github.com/tektoncd/pipeline/pkg/apis/config/resolver" + pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/internal/resolution" + ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" + frtesting "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework/testing" + common "github.com/tektoncd/pipeline/pkg/resolution/common" + resolutionframework "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" + frameworktesting "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework/testing" + gitresolution "github.com/tektoncd/pipeline/pkg/resolution/resolver/git" + "github.com/tektoncd/pipeline/test" + "github.com/tektoncd/pipeline/test/diff" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/system" + _ "knative.dev/pkg/system/testing" +) + +func TestGetSelector(t *testing.T) { + resolver := Resolver{} + sel := resolver.GetSelector(context.Background()) + if typ, has := sel[common.LabelKeyResolverType]; !has { + t.Fatalf("unexpected selector: %v", sel) + } else if typ != labelValueGitResolverType { + t.Fatalf("unexpected type: %q", typ) + } +} + +func TestValidateParams(t *testing.T) { + tests := []struct { + name string + wantErr string + params map[string]string + }{ + { + name: "params with revision", + params: map[string]string{ + gitresolution.UrlParam: "http://foo/bar/hello/moto", + gitresolution.PathParam: "bar", + gitresolution.RevisionParam: "baz", + }, + }, + { + name: "https url", + params: map[string]string{ + gitresolution.UrlParam: "https://foo/bar/hello/moto", + gitresolution.PathParam: "bar", + gitresolution.RevisionParam: "baz", + }, + }, + { + name: "https url with username password", + params: map[string]string{ + gitresolution.UrlParam: "https://user:pass@foo/bar/hello/moto", + gitresolution.PathParam: "bar", + gitresolution.RevisionParam: "baz", + }, + }, + { + name: "git server url", + params: map[string]string{ + gitresolution.UrlParam: "git://repo/hello/moto", + gitresolution.PathParam: "bar", + gitresolution.RevisionParam: "baz", + }, + }, + { + name: "git url from a local repository", + params: map[string]string{ + gitresolution.UrlParam: "/tmp/repo", + gitresolution.PathParam: "bar", + gitresolution.RevisionParam: "baz", + }, + }, + { + name: "git url from a git ssh repository", + params: map[string]string{ + gitresolution.UrlParam: "git@host.com:foo/bar", + gitresolution.PathParam: "bar", + gitresolution.RevisionParam: "baz", + }, + }, + { + name: "bad url", + params: map[string]string{ + gitresolution.UrlParam: "foo://bar", + gitresolution.PathParam: "path", + gitresolution.RevisionParam: "revision", + }, + wantErr: "invalid git repository url: foo://bar", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + resolver := Resolver{} + err := resolver.Validate(context.Background(), &v1beta1.ResolutionRequestSpec{Params: toParams(tt.params)}) + if tt.wantErr == "" { + if err != nil { + t.Fatalf("unexpected error validating params: %v", err) + } + return + } + + if d := cmp.Diff(tt.wantErr, err.Error()); d != "" { + t.Errorf("unexpected error: %s", diff.PrintWantGot(d)) + } + }) + } +} + +func TestValidateParamsNotEnabled(t *testing.T) { + resolver := Resolver{} + + var err error + + someParams := map[string]string{ + gitresolution.PathParam: "bar", + gitresolution.RevisionParam: "baz", + } + err = resolver.Validate(resolverDisabledContext(), &v1beta1.ResolutionRequestSpec{Params: toParams(someParams)}) + if err == nil { + t.Fatalf("expected disabled err") + } + if d := cmp.Diff(disabledError, err.Error()); d != "" { + t.Errorf("unexpected error: %s", diff.PrintWantGot(d)) + } +} + +func TestValidateParams_Failure(t *testing.T) { + testCases := []struct { + name string + params map[string]string + expectedErr string + }{ + { + name: "missing multiple", + params: map[string]string{ + gitresolution.OrgParam: "abcd1234", + gitresolution.RepoParam: "foo", + }, + expectedErr: fmt.Sprintf("missing required git resolver params: %s, %s", gitresolution.RevisionParam, gitresolution.PathParam), + }, { + name: "no repo or url", + params: map[string]string{ + gitresolution.RevisionParam: "abcd1234", + gitresolution.PathParam: "/foo/bar", + }, + expectedErr: "must specify one of 'url' or 'repo'", + }, { + name: "both repo and url", + params: map[string]string{ + gitresolution.RevisionParam: "abcd1234", + gitresolution.PathParam: "/foo/bar", + gitresolution.UrlParam: "http://foo", + gitresolution.RepoParam: "foo", + }, + expectedErr: "cannot specify both 'url' and 'repo'", + }, { + name: "no org with repo", + params: map[string]string{ + gitresolution.RevisionParam: "abcd1234", + gitresolution.PathParam: "/foo/bar", + gitresolution.RepoParam: "foo", + }, + expectedErr: "'org' is required when 'repo' is specified", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + resolver := &Resolver{} + err := resolver.Validate(context.Background(), &v1beta1.ResolutionRequestSpec{Params: toParams(tc.params)}) + if err == nil { + t.Fatalf("got no error, but expected: %s", tc.expectedErr) + } + if d := cmp.Diff(tc.expectedErr, err.Error()); d != "" { + t.Errorf("error did not match: %s", diff.PrintWantGot(d)) + } + }) + } +} + +func TestGetResolutionTimeoutDefault(t *testing.T) { + resolver := Resolver{} + defaultTimeout := 30 * time.Minute + timeout := resolver.GetResolutionTimeout(context.Background(), defaultTimeout) + if timeout != defaultTimeout { + t.Fatalf("expected default timeout to be returned") + } +} + +func TestGetResolutionTimeoutCustom(t *testing.T) { + resolver := Resolver{} + defaultTimeout := 30 * time.Minute + configTimeout := 5 * time.Second + config := map[string]string{ + gitresolution.DefaultTimeoutKey: configTimeout.String(), + } + ctx := resolutionframework.InjectResolverConfigToContext(context.Background(), config) + timeout := resolver.GetResolutionTimeout(ctx, defaultTimeout) + if timeout != configTimeout { + t.Fatalf("expected timeout from config to be returned") + } +} + +func TestResolveNotEnabled(t *testing.T) { + resolver := Resolver{} + + var err error + + someParams := map[string]string{ + gitresolution.PathParam: "bar", + gitresolution.RevisionParam: "baz", + } + _, err = resolver.Resolve(resolverDisabledContext(), &v1beta1.ResolutionRequestSpec{Params: toParams(someParams)}) + if err == nil { + t.Fatalf("expected disabled err") + } + if d := cmp.Diff(disabledError, err.Error()); d != "" { + t.Errorf("unexpected error: %s", diff.PrintWantGot(d)) + } +} + +type params struct { + url string + revision string + pathInRepo string + org string + repo string + token string + tokenKey string + namespace string + serverURL string + scmType string +} + +func TestResolve(t *testing.T) { + // local repo set up for anonymous cloning + // ---- + commits := []commitForRepo{{ + Dir: "foo/", + Filename: "old", + Content: "old content in test branch", + Branch: "test-branch", + }, { + Dir: "foo/", + Filename: "new", + Content: "new content in test branch", + Branch: "test-branch", + }, { + Dir: "./", + Filename: "released", + Content: "released content in main branch and in tag v1", + Tag: "v1", + }} + + anonFakeRepoURL, commitSHAsInAnonRepo := createTestRepo(t, commits) + + // local repo set up for scm cloning + // ---- + withTemporaryGitConfig(t) + + testOrg := "test-org" + testRepo := "test-repo" + + refsDir := filepath.Join("testdata", "test-org", "test-repo", "refs") + mainPipelineYAML, err := os.ReadFile(filepath.Join(refsDir, "main", "pipelines", "example-pipeline.yaml")) + if err != nil { + t.Fatalf("couldn't read main pipeline: %v", err) + } + otherPipelineYAML, err := os.ReadFile(filepath.Join(refsDir, "other", "pipelines", "example-pipeline.yaml")) + if err != nil { + t.Fatalf("couldn't read other pipeline: %v", err) + } + + mainTaskYAML, err := os.ReadFile(filepath.Join(refsDir, "main", "tasks", "example-task.yaml")) + if err != nil { + t.Fatalf("couldn't read main task: %v", err) + } + + commitSHAsInSCMRepo := []string{"abc", "xyz"} + + scmFakeRepoURL := fmt.Sprintf("https://fake/%s/%s.git", testOrg, testRepo) + resolver := &Resolver{ + clientFunc: func(driver string, serverURL string, token string, opts ...factory.ClientOptionFunc) (*scm.Client, error) { + scmClient, scmData := fake.NewDefault() + + // repository service + scmData.Repositories = []*scm.Repository{{ + FullName: fmt.Sprintf("%s/%s", testOrg, testRepo), + Clone: scmFakeRepoURL, + }} + + // git service + scmData.Commits = map[string]*scm.Commit{ + "main": {Sha: commitSHAsInSCMRepo[0]}, + "other": {Sha: commitSHAsInSCMRepo[1]}, + } + return scmClient, nil + }, + } + + testCases := []struct { + name string + args *params + config map[string]string + apiToken string + expectedCommitSHA string + expectedStatus *v1beta1.ResolutionRequestStatus + expectedErr error + }{{ + name: "clone: default revision main", + args: ¶ms{ + pathInRepo: "./released", + url: anonFakeRepoURL, + }, + expectedCommitSHA: commitSHAsInAnonRepo[2], + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte("released content in main branch and in tag v1")), + }, { + name: "clone: revision is tag name", + args: ¶ms{ + revision: "v1", + pathInRepo: "./released", + url: anonFakeRepoURL, + }, + expectedCommitSHA: commitSHAsInAnonRepo[2], + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte("released content in main branch and in tag v1")), + }, { + name: "clone: revision is the full tag name i.e. refs/tags/v1", + args: ¶ms{ + revision: "refs/tags/v1", + pathInRepo: "./released", + url: anonFakeRepoURL, + }, + expectedCommitSHA: commitSHAsInAnonRepo[2], + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte("released content in main branch and in tag v1")), + }, { + name: "clone: revision is a branch name", + args: ¶ms{ + revision: "test-branch", + pathInRepo: "foo/new", + url: anonFakeRepoURL, + }, + expectedCommitSHA: commitSHAsInAnonRepo[1], + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte("new content in test branch")), + }, { + name: "clone: revision is a specific commit sha", + args: ¶ms{ + revision: commitSHAsInAnonRepo[0], + pathInRepo: "foo/old", + url: anonFakeRepoURL, + }, + expectedCommitSHA: commitSHAsInAnonRepo[0], + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte("old content in test branch")), + }, { + name: "clone: file does not exist", + args: ¶ms{ + pathInRepo: "foo/non-exist", + url: anonFakeRepoURL, + }, + expectedErr: createError(`error opening file "foo/non-exist": file does not exist`), + }, { + name: "clone: revision does not exist", + args: ¶ms{ + revision: "non-existent-revision", + pathInRepo: "foo/new", + url: anonFakeRepoURL, + }, + expectedErr: createError("revision error: reference not found"), + }, { + name: "api: successful task from params api information", + args: ¶ms{ + revision: "main", + pathInRepo: "tasks/example-task.yaml", + org: testOrg, + repo: testRepo, + token: "token-secret", + tokenKey: "token", + namespace: "foo", + }, + config: map[string]string{ + gitresolution.ServerURLKey: "fake", + gitresolution.SCMTypeKey: "fake", + }, + apiToken: "some-token", + expectedCommitSHA: commitSHAsInSCMRepo[0], + expectedStatus: resolution.CreateResolutionRequestStatusWithData(mainTaskYAML), + }, { + name: "api: successful task", + args: ¶ms{ + revision: "main", + pathInRepo: "tasks/example-task.yaml", + org: testOrg, + repo: testRepo, + }, + config: map[string]string{ + gitresolution.ServerURLKey: "fake", + gitresolution.SCMTypeKey: "fake", + gitresolution.APISecretNameKey: "token-secret", + gitresolution.APISecretKeyKey: "token", + gitresolution.APISecretNamespaceKey: system.Namespace(), + }, + apiToken: "some-token", + expectedCommitSHA: commitSHAsInSCMRepo[0], + expectedStatus: resolution.CreateResolutionRequestStatusWithData(mainTaskYAML), + }, { + name: "api: successful pipeline", + args: ¶ms{ + revision: "main", + pathInRepo: "pipelines/example-pipeline.yaml", + org: testOrg, + repo: testRepo, + }, + config: map[string]string{ + gitresolution.ServerURLKey: "fake", + gitresolution.SCMTypeKey: "fake", + gitresolution.APISecretNameKey: "token-secret", + gitresolution.APISecretKeyKey: "token", + gitresolution.APISecretNamespaceKey: system.Namespace(), + }, + apiToken: "some-token", + expectedCommitSHA: commitSHAsInSCMRepo[0], + expectedStatus: resolution.CreateResolutionRequestStatusWithData(mainPipelineYAML), + }, { + name: "api: successful pipeline with default revision", + args: ¶ms{ + pathInRepo: "pipelines/example-pipeline.yaml", + org: testOrg, + repo: testRepo, + }, + config: map[string]string{ + gitresolution.ServerURLKey: "fake", + gitresolution.SCMTypeKey: "fake", + gitresolution.APISecretNameKey: "token-secret", + gitresolution.APISecretKeyKey: "token", + gitresolution.APISecretNamespaceKey: system.Namespace(), + gitresolution.DefaultRevisionKey: "other", + }, + apiToken: "some-token", + expectedCommitSHA: commitSHAsInSCMRepo[1], + expectedStatus: resolution.CreateResolutionRequestStatusWithData(otherPipelineYAML), + }, { + name: "api: successful override scm type and server URL from user params", + + args: ¶ms{ + revision: "main", + pathInRepo: "tasks/example-task.yaml", + org: testOrg, + repo: testRepo, + token: "token-secret", + tokenKey: "token", + namespace: "foo", + scmType: "fake", + serverURL: "fake", + }, + config: map[string]string{ + gitresolution.ServerURLKey: "notsofake", + gitresolution.SCMTypeKey: "definitivelynotafake", + }, + apiToken: "some-token", + expectedCommitSHA: commitSHAsInSCMRepo[0], + expectedStatus: resolution.CreateResolutionRequestStatusWithData(mainTaskYAML), + }, { + name: "api: file does not exist", + args: ¶ms{ + revision: "main", + pathInRepo: "pipelines/other-pipeline.yaml", + org: testOrg, + repo: testRepo, + }, + config: map[string]string{ + gitresolution.ServerURLKey: "fake", + gitresolution.SCMTypeKey: "fake", + gitresolution.APISecretNameKey: "token-secret", + gitresolution.APISecretKeyKey: "token", + gitresolution.APISecretNamespaceKey: system.Namespace(), + }, + apiToken: "some-token", + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErr: createError("couldn't fetch resource content: file testdata/test-org/test-repo/refs/main/pipelines/other-pipeline.yaml does not exist: stat testdata/test-org/test-repo/refs/main/pipelines/other-pipeline.yaml: no such file or directory"), + }, { + name: "api: token not found", + args: ¶ms{ + revision: "main", + pathInRepo: "pipelines/example-pipeline.yaml", + org: testOrg, + repo: testRepo, + }, + config: map[string]string{ + gitresolution.ServerURLKey: "fake", + gitresolution.SCMTypeKey: "fake", + gitresolution.APISecretNameKey: "token-secret", + gitresolution.APISecretKeyKey: "token", + gitresolution.APISecretNamespaceKey: system.Namespace(), + }, + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErr: createError("cannot get API token, secret token-secret not found in namespace " + system.Namespace()), + }, { + name: "api: token secret name not specified", + args: ¶ms{ + revision: "main", + pathInRepo: "pipelines/example-pipeline.yaml", + org: testOrg, + repo: testRepo, + }, + config: map[string]string{ + gitresolution.ServerURLKey: "fake", + gitresolution.SCMTypeKey: "fake", + gitresolution.APISecretKeyKey: "token", + gitresolution.APISecretNamespaceKey: system.Namespace(), + }, + apiToken: "some-token", + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErr: createError("cannot get API token, required when specifying 'repo' param, 'api-token-secret-name' not specified in config"), + }, { + name: "api: token secret key not specified", + args: ¶ms{ + revision: "main", + pathInRepo: "pipelines/example-pipeline.yaml", + org: testOrg, + repo: testRepo, + }, + config: map[string]string{ + gitresolution.ServerURLKey: "fake", + gitresolution.SCMTypeKey: "fake", + gitresolution.APISecretNameKey: "token-secret", + gitresolution.APISecretNamespaceKey: system.Namespace(), + }, + apiToken: "some-token", + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErr: createError("cannot get API token, required when specifying 'repo' param, 'api-token-secret-key' not specified in config"), + }, { + name: "api: SCM type not specified", + args: ¶ms{ + revision: "main", + pathInRepo: "pipelines/example-pipeline.yaml", + org: testOrg, + repo: testRepo, + }, + config: map[string]string{ + gitresolution.APISecretNameKey: "token-secret", + gitresolution.APISecretKeyKey: "token", + gitresolution.APISecretNamespaceKey: system.Namespace(), + }, + apiToken: "some-token", + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErr: createError("missing or empty scm-type value in configmap"), + }} + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + ctx, _ := ttesting.SetupFakeContext(t) + + cfg := tc.config + if cfg == nil { + cfg = make(map[string]string) + } + cfg[gitresolution.DefaultTimeoutKey] = "1m" + if cfg[gitresolution.DefaultRevisionKey] == "" { + cfg[gitresolution.DefaultRevisionKey] = plumbing.Master.Short() + } + + request := createRequest(tc.args) + + d := test.Data{ + ConfigMaps: []*corev1.ConfigMap{{ + ObjectMeta: metav1.ObjectMeta{ + Name: ConfigMapName, + Namespace: resolverconfig.ResolversNamespace(system.Namespace()), + }, + Data: cfg, + }, { + ObjectMeta: metav1.ObjectMeta{ + Namespace: resolverconfig.ResolversNamespace(system.Namespace()), + Name: resolverconfig.GetFeatureFlagsConfigName(), + }, + Data: map[string]string{ + "enable-git-resolver": "true", + }, + }}, + ResolutionRequests: []*v1beta1.ResolutionRequest{request}, + } + + var expectedStatus *v1beta1.ResolutionRequestStatus + if tc.expectedStatus != nil { + expectedStatus = tc.expectedStatus.DeepCopy() + + if tc.expectedErr == nil { + // status.annotations + if expectedStatus.Annotations == nil { + expectedStatus.Annotations = make(map[string]string) + } + expectedStatus.Annotations[common.AnnotationKeyContentType] = "application/x-yaml" + expectedStatus.Annotations[gitresolution.AnnotationKeyRevision] = tc.expectedCommitSHA + expectedStatus.Annotations[gitresolution.AnnotationKeyPath] = tc.args.pathInRepo + + if tc.args.url != "" { + expectedStatus.Annotations[gitresolution.AnnotationKeyURL] = anonFakeRepoURL + } else { + expectedStatus.Annotations[gitresolution.AnnotationKeyOrg] = testOrg + expectedStatus.Annotations[gitresolution.AnnotationKeyRepo] = testRepo + expectedStatus.Annotations[gitresolution.AnnotationKeyURL] = scmFakeRepoURL + } + + // status.refSource + expectedStatus.RefSource = &pipelinev1.RefSource{ + URI: "git+" + expectedStatus.Annotations[gitresolution.AnnotationKeyURL], + Digest: map[string]string{ + "sha1": tc.expectedCommitSHA, + }, + EntryPoint: tc.args.pathInRepo, + } + expectedStatus.Source = expectedStatus.RefSource + } else { + expectedStatus.Status.Conditions[0].Message = tc.expectedErr.Error() + } + } + + frtesting.RunResolverReconcileTest(ctx, t, d, resolver, request, expectedStatus, tc.expectedErr, func(resolver framework.Resolver, testAssets test.Assets) { + var secretName, secretNameKey, secretNamespace string + if tc.config[gitresolution.APISecretNameKey] != "" && tc.config[gitresolution.APISecretNamespaceKey] != "" && tc.config[gitresolution.APISecretKeyKey] != "" && tc.apiToken != "" { + secretName, secretNameKey, secretNamespace = tc.config[gitresolution.APISecretNameKey], tc.config[gitresolution.APISecretKeyKey], tc.config[gitresolution.APISecretNamespaceKey] + } + if tc.args.token != "" && tc.args.namespace != "" && tc.args.tokenKey != "" { + secretName, secretNameKey, secretNamespace = tc.args.token, tc.args.tokenKey, tc.args.namespace + } + if secretName == "" || secretNameKey == "" || secretNamespace == "" { + return + } + tokenSecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: secretName, + Namespace: secretNamespace, + }, + Data: map[string][]byte{ + secretNameKey: []byte(base64.StdEncoding.Strict().EncodeToString([]byte(tc.apiToken))), + }, + Type: corev1.SecretTypeOpaque, + } + if _, err := testAssets.Clients.Kube.CoreV1().Secrets(secretNamespace).Create(ctx, tokenSecret, metav1.CreateOptions{}); err != nil { + t.Fatalf("failed to create test token secret: %v", err) + } + }) + }) + } +} + +// createTestRepo is used to instantiate a local test repository with the desired commits. +func createTestRepo(t *testing.T, commits []commitForRepo) (string, []string) { + t.Helper() + commitSHAs := []string{} + + t.Helper() + tempDir := t.TempDir() + + repo, err := git.PlainInit(tempDir, false) + + worktree, err := repo.Worktree() + if err != nil { + t.Fatalf("getting test worktree: %v", err) + } + if worktree == nil { + t.Fatal("test worktree not created") + } + + startingHash := writeAndCommitToTestRepo(t, worktree, tempDir, "", "README", []byte("This is a test")) + + hashesByBranch := make(map[string][]string) + + // Iterate over the commits and add them. + for _, cmt := range commits { + branch := cmt.Branch + if branch == "" { + branch = plumbing.Master.Short() + } + + // If we're given a revision, check out that revision. + coOpts := &git.CheckoutOptions{ + Branch: plumbing.NewBranchReferenceName(branch), + } + + if _, ok := hashesByBranch[branch]; !ok && branch != plumbing.Master.Short() { + coOpts.Hash = plumbing.NewHash(startingHash.String()) + coOpts.Create = true + } + + if err := worktree.Checkout(coOpts); err != nil { + t.Fatalf("couldn't do checkout of %s: %v", branch, err) + } + + hash := writeAndCommitToTestRepo(t, worktree, tempDir, cmt.Dir, cmt.Filename, []byte(cmt.Content)) + commitSHAs = append(commitSHAs, hash.String()) + + if _, ok := hashesByBranch[branch]; !ok { + hashesByBranch[branch] = []string{hash.String()} + } else { + hashesByBranch[branch] = append(hashesByBranch[branch], hash.String()) + } + + if cmt.Tag != "" { + _, err = repo.CreateTag(cmt.Tag, hash, &git.CreateTagOptions{ + Message: cmt.Tag, + Tagger: &object.Signature{ + Name: "Someone", + Email: "someone@example.com", + When: time.Now(), + }, + }) + } + if err != nil { + t.Fatalf("couldn't add tag for %s: %v", cmt.Tag, err) + } + } + + return tempDir, commitSHAs +} + +// commitForRepo provides the directory, filename, content and revision for a test commit. +type commitForRepo struct { + Dir string + Filename string + Content string + Branch string + Tag string +} + +func writeAndCommitToTestRepo(t *testing.T, worktree *git.Worktree, repoDir string, subPath string, filename string, content []byte) plumbing.Hash { + t.Helper() + + targetDir := repoDir + if subPath != "" { + targetDir = filepath.Join(targetDir, subPath) + fi, err := os.Stat(targetDir) + if os.IsNotExist(err) { + if err := os.MkdirAll(targetDir, 0o700); err != nil { + t.Fatalf("couldn't create directory %s in worktree: %v", targetDir, err) + } + } else if err != nil { + t.Fatalf("checking if directory %s in worktree exists: %v", targetDir, err) + } + if fi != nil && !fi.IsDir() { + t.Fatalf("%s already exists but is not a directory", targetDir) + } + } + + outfile := filepath.Join(targetDir, filename) + if err := os.WriteFile(outfile, content, 0o600); err != nil { + t.Fatalf("couldn't write content to file %s: %v", outfile, err) + } + + _, err := worktree.Add(filepath.Join(subPath, filename)) + if err != nil { + t.Fatalf("couldn't add file %s to git: %v", outfile, err) + } + + hash, err := worktree.Commit("adding file for test", &git.CommitOptions{ + Author: &object.Signature{ + Name: "Someone", + Email: "someone@example.com", + When: time.Now(), + }, + }) + if err != nil { + t.Fatalf("couldn't perform commit for test: %v", err) + } + + return hash +} + +// withTemporaryGitConfig resets the .gitconfig for the duration of the test. +func withTemporaryGitConfig(t *testing.T) { + t.Helper() + gitConfigDir := t.TempDir() + key := "GIT_CONFIG_GLOBAL" + t.Setenv(key, filepath.Join(gitConfigDir, "config")) +} + +func createRequest(args *params) *v1beta1.ResolutionRequest { + rr := &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{ + common.LabelKeyResolverType: labelValueGitResolverType, + }, + }, + Spec: v1beta1.ResolutionRequestSpec{ + Params: []pipelinev1.Param{{ + Name: gitresolution.PathParam, + Value: *pipelinev1.NewStructuredValues(args.pathInRepo), + }}, + }, + } + + if args.revision != "" { + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: gitresolution.RevisionParam, + Value: *pipelinev1.NewStructuredValues(args.revision), + }) + } + + if args.serverURL != "" { + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: gitresolution.ServerURLParam, + Value: *pipelinev1.NewStructuredValues(args.serverURL), + }) + } + if args.scmType != "" { + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: gitresolution.ScmTypeParam, + Value: *pipelinev1.NewStructuredValues(args.scmType), + }) + } + + if args.url != "" { + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: gitresolution.UrlParam, + Value: *pipelinev1.NewStructuredValues(args.url), + }) + } else { + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: gitresolution.RepoParam, + Value: *pipelinev1.NewStructuredValues(args.repo), + }) + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: gitresolution.OrgParam, + Value: *pipelinev1.NewStructuredValues(args.org), + }) + if args.token != "" { + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: gitresolution.TokenParam, + Value: *pipelinev1.NewStructuredValues(args.token), + }) + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: gitresolution.TokenKeyParam, + Value: *pipelinev1.NewStructuredValues(args.tokenKey), + }) + } + } + + return rr +} + +func resolverDisabledContext() context.Context { + return frameworktesting.ContextWithGitResolverDisabled(context.Background()) +} + +func createError(msg string) error { + return &common.GetResourceError{ + ResolverName: gitResolverName, + Key: "foo/rr", + Original: errors.New(msg), + } +} + +func toParams(m map[string]string) []pipelinev1.Param { + var params []pipelinev1.Param + + for k, v := range m { + params = append(params, pipelinev1.Param{ + Name: k, + Value: *pipelinev1.NewStructuredValues(v), + }) + } + + return params +} diff --git a/pkg/remoteresolution/resolver/git/testdata/test-org/test-repo/refs/main/pipelines/example-pipeline.yaml b/pkg/remoteresolution/resolver/git/testdata/test-org/test-repo/refs/main/pipelines/example-pipeline.yaml new file mode 100644 index 00000000000..cc697dd2e91 --- /dev/null +++ b/pkg/remoteresolution/resolver/git/testdata/test-org/test-repo/refs/main/pipelines/example-pipeline.yaml @@ -0,0 +1,10 @@ +apiVersion: tekton.dev/v1beta1 +kind: Pipeline +metadata: + name: example-pipeline +spec: + tasks: + - name: some-pipeline-task + taskRef: + kind: Task + name: some-task diff --git a/pkg/remoteresolution/resolver/git/testdata/test-org/test-repo/refs/main/tasks/example-task.yaml b/pkg/remoteresolution/resolver/git/testdata/test-org/test-repo/refs/main/tasks/example-task.yaml new file mode 100644 index 00000000000..97ad418341e --- /dev/null +++ b/pkg/remoteresolution/resolver/git/testdata/test-org/test-repo/refs/main/tasks/example-task.yaml @@ -0,0 +1,9 @@ +apiVersion: tekton.dev/v1beta1 +kind: Task +metadata: + name: example-task +spec: + steps: + - command: ['something'] + image: some-image + name: some-step diff --git a/pkg/remoteresolution/resolver/git/testdata/test-org/test-repo/refs/other/pipelines/example-pipeline.yaml b/pkg/remoteresolution/resolver/git/testdata/test-org/test-repo/refs/other/pipelines/example-pipeline.yaml new file mode 100644 index 00000000000..836822c6fa4 --- /dev/null +++ b/pkg/remoteresolution/resolver/git/testdata/test-org/test-repo/refs/other/pipelines/example-pipeline.yaml @@ -0,0 +1,10 @@ +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: example-pipeline +spec: + tasks: + - name: some-pipeline-task + taskRef: + kind: Task + name: some-other-task diff --git a/pkg/remoteresolution/resolver/http/resolver.go b/pkg/remoteresolution/resolver/http/resolver.go new file mode 100644 index 00000000000..3a0a5d48f0c --- /dev/null +++ b/pkg/remoteresolution/resolver/http/resolver.go @@ -0,0 +1,100 @@ +/* +Copyright 2024 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package http + +import ( + "context" + "errors" + + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" + "github.com/tektoncd/pipeline/pkg/resolution/common" + resolutionframework "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" + "github.com/tektoncd/pipeline/pkg/resolution/resolver/http" + "go.uber.org/zap" + "k8s.io/client-go/kubernetes" + kubeclient "knative.dev/pkg/client/injection/kube/client" + "knative.dev/pkg/logging" +) + +const ( + // LabelValueHttpResolverType is the value to use for the + // resolution.tekton.dev/type label on resource requests + LabelValueHttpResolverType string = "http" + + disabledError = "cannot handle resolution request, enable-http-resolver feature flag not true" + + // httpResolverName The name of the resolver + httpResolverName = "Http" + + // configMapName is the http resolver's config map + configMapName = "http-resolver-config" + + // default Timeout value when fetching http resources in seconds + defaultHttpTimeoutValue = "1m" + + // default key in the HTTP password secret + defaultBasicAuthSecretKey = "password" +) + +var _ framework.Resolver = &Resolver{} + +// Resolver implements a framework.Resolver that can fetch files from an HTTP URL +type Resolver struct { + kubeClient kubernetes.Interface + logger *zap.SugaredLogger +} + +func (r *Resolver) Initialize(ctx context.Context) error { + r.kubeClient = kubeclient.Get(ctx) + r.logger = logging.FromContext(ctx) + return nil +} + +// GetName returns a string name to refer to this resolver by. +func (r *Resolver) GetName(context.Context) string { + return httpResolverName +} + +// GetConfigName returns the name of the http resolver's configmap. +func (r *Resolver) GetConfigName(context.Context) string { + return configMapName +} + +// GetSelector returns a map of labels to match requests to this resolver. +func (r *Resolver) GetSelector(context.Context) map[string]string { + return map[string]string{ + common.LabelKeyResolverType: LabelValueHttpResolverType, + } +} + +// Validate ensures parameters from a request are as expected. +func (r *Resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestSpec) error { + return http.ValidateParams(ctx, req.Params) +} + +// Resolve uses the given params to resolve the requested file or resource. +func (r *Resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (resolutionframework.ResolvedResource, error) { + oParams := req.Params + if http.IsDisabled(ctx) { + return nil, errors.New(disabledError) + } + + params, err := http.PopulateDefaultParams(ctx, oParams) + if err != nil { + return nil, err + } + + return http.FetchHttpResource(ctx, params, r.kubeClient, r.logger) +} diff --git a/pkg/remoteresolution/resolver/http/resolver_test.go b/pkg/remoteresolution/resolver/http/resolver_test.go new file mode 100644 index 00000000000..f6d4634822e --- /dev/null +++ b/pkg/remoteresolution/resolver/http/resolver_test.go @@ -0,0 +1,503 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package http + +import ( + "context" + "crypto/sha256" + "encoding/base64" + "encoding/hex" + "errors" + "fmt" + "net/http" + "net/http/httptest" + "regexp" + "testing" + "time" + + "github.com/google/go-cmp/cmp" + resolverconfig "github.com/tektoncd/pipeline/pkg/apis/config/resolver" + pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/internal/resolution" + ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" + frtesting "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework/testing" + resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + resolutionframework "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" + frameworktesting "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework/testing" + httpresolution "github.com/tektoncd/pipeline/pkg/resolution/resolver/http" + "github.com/tektoncd/pipeline/test" + "github.com/tektoncd/pipeline/test/diff" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/system" + _ "knative.dev/pkg/system/testing" +) + +type params struct { + url string + authUsername string + authSecret string + authSecretKey string + authSecretContent string +} + +const sampleTask = `--- +kind: Task +apiVersion: tekton.dev/v1 +metadata: + name: foo +spec: + steps: + - name: step1 + image: scratch` +const emptyStr = "empty" + +func TestGetSelector(t *testing.T) { + resolver := Resolver{} + sel := resolver.GetSelector(context.Background()) + if typ, has := sel[resolutioncommon.LabelKeyResolverType]; !has { + t.Fatalf("unexpected selector: %v", sel) + } else if typ != LabelValueHttpResolverType { + t.Fatalf("unexpected type: %q", typ) + } +} + +func TestValidate(t *testing.T) { + testCases := []struct { + name string + url string + expectedErr error + }{ + { + name: "valid/url", + url: "https://raw.githubusercontent.com/tektoncd/catalog/main/task/git-clone/0.4/git-clone.yaml", + }, { + name: "invalid/url", + url: "xttps:ufoo/bar/", + expectedErr: errors.New(`url xttps:ufoo/bar/ is not a valid http(s) url`), + }, { + name: "invalid/url empty", + url: "", + expectedErr: errors.New(`cannot parse url : parse "": empty url`), + }, { + name: "missing/url", + expectedErr: errors.New(`missing required http resolver params: url`), + url: "nourl", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + resolver := Resolver{} + params := map[string]string{} + if tc.url != "nourl" { + params[httpresolution.UrlParam] = tc.url + } + req := v1beta1.ResolutionRequestSpec{ + Params: toParams(params), + } + err := resolver.Validate(contextWithConfig(defaultHttpTimeoutValue), &req) + if tc.expectedErr != nil { + checkExpectedErr(t, tc.expectedErr, err) + } else if err != nil { + t.Fatalf("unexpected error validating params: %v", err) + } + }) + } +} + +func TestResolve(t *testing.T) { + tests := []struct { + name string + expectedErr string + input string + paramSet bool + expectedStatus int + }{ + { + name: "good/params set", + input: "task", + paramSet: true, + }, { + name: "bad/params not set", + input: "task", + expectedErr: `missing required http resolver params: url`, + }, { + name: "bad/not found", + input: "task", + paramSet: true, + expectedStatus: http.StatusNotFound, + expectedErr: `requested URL 'http://([^']*)' is not found`, + }, + } + for _, tc := range tests { + t.Run(tc.name, func(t *testing.T) { + svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + if tc.expectedStatus != 0 { + w.WriteHeader(tc.expectedStatus) + } + fmt.Fprintf(w, tc.input) + })) + params := []pipelinev1.Param{} + if tc.paramSet { + params = append(params, pipelinev1.Param{ + Name: httpresolution.UrlParam, + Value: *pipelinev1.NewStructuredValues(svr.URL), + }) + } + resolver := Resolver{} + req := v1beta1.ResolutionRequestSpec{ + Params: params, + } + output, err := resolver.Resolve(contextWithConfig(defaultHttpTimeoutValue), &req) + if tc.expectedErr != "" { + re := regexp.MustCompile(tc.expectedErr) + if !re.MatchString(err.Error()) { + t.Fatalf("expected error '%v' but got '%v'", tc.expectedErr, err) + } + return + } else if err != nil { + t.Fatalf("unexpected error validating params: %v", err) + } + if o := cmp.Diff(tc.input, string(output.Data())); o != "" { + t.Fatalf("expected output '%v' but got '%v'", tc.input, string(output.Data())) + } + if o := cmp.Diff(svr.URL, output.RefSource().URI); o != "" { + t.Fatalf("expected url '%v' but got '%v'", svr.URL, output.RefSource().URI) + } + + eSum := sha256.New() + eSum.Write([]byte(tc.input)) + eSha256 := hex.EncodeToString(eSum.Sum(nil)) + if o := cmp.Diff(eSha256, output.RefSource().Digest["sha256"]); o != "" { + t.Fatalf("expected sha256 '%v' but got '%v'", eSha256, output.RefSource().Digest["sha256"]) + } + + if output.Annotations() != nil { + t.Fatalf("output annotations should be nil") + } + }) + } +} + +func TestResolveNotEnabled(t *testing.T) { + var err error + resolver := Resolver{} + someParams := map[string]string{} + req := v1beta1.ResolutionRequestSpec{ + Params: toParams(someParams), + } + _, err = resolver.Resolve(resolverDisabledContext(), &req) + if err == nil { + t.Fatalf("expected disabled err") + } + if d := cmp.Diff(disabledError, err.Error()); d != "" { + t.Errorf("unexpected error: %s", diff.PrintWantGot(d)) + } + err = resolver.Validate(resolverDisabledContext(), &v1beta1.ResolutionRequestSpec{Params: toParams(map[string]string{})}) + if err == nil { + t.Fatalf("expected disabled err") + } + if d := cmp.Diff(disabledError, err.Error()); d != "" { + t.Errorf("unexpected error: %s", diff.PrintWantGot(d)) + } +} + +func TestResolverReconcileBasicAuth(t *testing.T) { + var doNotCreate string = "notcreate" + var wrongSecretKey string = "wrongsecretk" + + tests := []struct { + name string + params *params + taskContent string + expectedStatus *v1beta1.ResolutionRequestStatus + expectedErr error + }{ + { + name: "good/URL Resolution", + taskContent: sampleTask, + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte(sampleTask)), + }, + { + name: "good/URL Resolution with custom basic auth, and custom secret key", + taskContent: sampleTask, + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte(sampleTask)), + params: ¶ms{ + authSecret: "auth-secret", + authUsername: "auth", + authSecretKey: "token", + authSecretContent: "untoken", + }, + }, + { + name: "good/URL Resolution with custom basic auth no custom secret key", + taskContent: sampleTask, + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte(sampleTask)), + params: ¶ms{ + authSecret: "auth-secret", + authUsername: "auth", + authSecretContent: "untoken", + }, + }, + { + name: "bad/no url found", + params: ¶ms{}, + expectedErr: errors.New(`invalid resource request "foo/rr": cannot parse url : parse "": empty url`), + }, + { + name: "bad/no secret found", + params: ¶ms{ + authSecret: doNotCreate, + authUsername: "user", + url: "https://blah/blah.com", + }, + expectedErr: errors.New(`error getting "Http" "foo/rr": cannot get API token, secret notcreate not found in namespace foo`), + }, + { + name: "bad/no valid secret key", + params: ¶ms{ + authSecret: "shhhhh", + authUsername: "user", + authSecretKey: wrongSecretKey, + url: "https://blah/blah", + }, + expectedErr: errors.New(`error getting "Http" "foo/rr": cannot get API token, key wrongsecretk not found in secret shhhhh in namespace foo`), + }, + { + name: "bad/missing username params for secret with params", + params: ¶ms{ + authSecret: "shhhhh", + url: "https://blah/blah", + }, + expectedErr: errors.New(`invalid resource request "foo/rr": missing required param http-username when using http-password-secret`), + }, + { + name: "bad/missing password params for secret with username", + params: ¶ms{ + authUsername: "failure", + url: "https://blah/blah", + }, + expectedErr: errors.New(`invalid resource request "foo/rr": missing required param http-password-secret when using http-username`), + }, + { + name: "bad/empty auth username", + params: ¶ms{ + authUsername: emptyStr, + authSecret: "asecret", + url: "https://blah/blah", + }, + expectedErr: errors.New(`invalid resource request "foo/rr": value http-username cannot be empty`), + }, + { + name: "bad/empty auth password", + params: ¶ms{ + authUsername: "auser", + authSecret: emptyStr, + url: "https://blah/blah", + }, + expectedErr: errors.New(`invalid resource request "foo/rr": value http-password-secret cannot be empty`), + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + resolver := &Resolver{} + ctx, _ := ttesting.SetupFakeContext(t) + svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, tt.taskContent) + })) + p := tt.params + if p == nil { + p = ¶ms{} + } + if p.url == "" && tt.taskContent != "" { + p.url = svr.URL + } + request := createRequest(p) + cfg := make(map[string]string) + d := test.Data{ + ConfigMaps: []*corev1.ConfigMap{{ + ObjectMeta: metav1.ObjectMeta{ + Name: configMapName, + Namespace: resolverconfig.ResolversNamespace(system.Namespace()), + }, + Data: cfg, + }, { + ObjectMeta: metav1.ObjectMeta{ + Namespace: resolverconfig.ResolversNamespace(system.Namespace()), + Name: resolverconfig.GetFeatureFlagsConfigName(), + }, + Data: map[string]string{ + "enable-http-resolver": "true", + }, + }}, + ResolutionRequests: []*v1beta1.ResolutionRequest{request}, + } + var expectedStatus *v1beta1.ResolutionRequestStatus + if tt.expectedStatus != nil { + expectedStatus = tt.expectedStatus.DeepCopy() + if tt.expectedErr == nil { + if tt.taskContent != "" { + h := sha256.New() + h.Write([]byte(tt.taskContent)) + sha256CheckSum := hex.EncodeToString(h.Sum(nil)) + refsrc := &pipelinev1.RefSource{ + URI: svr.URL, + Digest: map[string]string{ + "sha256": sha256CheckSum, + }, + } + expectedStatus.RefSource = refsrc + expectedStatus.Source = refsrc + } + } else { + expectedStatus.Status.Conditions[0].Message = tt.expectedErr.Error() + } + } + frtesting.RunResolverReconcileTest(ctx, t, d, resolver, request, expectedStatus, tt.expectedErr, func(resolver framework.Resolver, testAssets test.Assets) { + if err := resolver.Initialize(ctx); err != nil { + t.Errorf("unexpected error: %v", err) + } + if tt.params == nil { + return + } + if tt.params.authSecret != "" && tt.params.authSecret != doNotCreate { + secretKey := tt.params.authSecretKey + if secretKey == wrongSecretKey { + secretKey = "randomNotOund" + } + if secretKey == "" { + secretKey = defaultBasicAuthSecretKey + } + tokenSecret := &corev1.Secret{ + ObjectMeta: metav1.ObjectMeta{ + Name: tt.params.authSecret, + Namespace: request.GetNamespace(), + }, + Data: map[string][]byte{ + secretKey: []byte(base64.StdEncoding.Strict().EncodeToString([]byte(tt.params.authSecretContent))), + }, + } + if _, err := testAssets.Clients.Kube.CoreV1().Secrets(request.GetNamespace()).Create(ctx, tokenSecret, metav1.CreateOptions{}); err != nil { + t.Fatalf("failed to create test token secret: %v", err) + } + } + }) + }) + } +} + +func TestGetName(t *testing.T) { + resolver := Resolver{} + ctx := context.Background() + + if d := cmp.Diff(httpResolverName, resolver.GetName(ctx)); d != "" { + t.Errorf("invalid name: %s", diff.PrintWantGot(d)) + } + if d := cmp.Diff(configMapName, resolver.GetConfigName(ctx)); d != "" { + t.Errorf("invalid config map name: %s", diff.PrintWantGot(d)) + } +} + +func resolverDisabledContext() context.Context { + return frameworktesting.ContextWithHttpResolverDisabled(context.Background()) +} + +func toParams(m map[string]string) []pipelinev1.Param { + var params []pipelinev1.Param + + for k, v := range m { + params = append(params, pipelinev1.Param{ + Name: k, + Value: *pipelinev1.NewStructuredValues(v), + }) + } + + return params +} + +func contextWithConfig(timeout string) context.Context { + config := map[string]string{ + httpresolution.TimeoutKey: timeout, + } + return resolutionframework.InjectResolverConfigToContext(context.Background(), config) +} + +func checkExpectedErr(t *testing.T, expectedErr, actualErr error) { + t.Helper() + if actualErr == nil { + t.Fatalf("expected err '%v' but didn't get one", expectedErr) + } + if d := cmp.Diff(expectedErr.Error(), actualErr.Error()); d != "" { + t.Fatalf("expected err '%v' but got '%v'", expectedErr, actualErr) + } +} + +func createRequest(params *params) *v1beta1.ResolutionRequest { + rr := &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: LabelValueHttpResolverType, + }, + }, + Spec: v1beta1.ResolutionRequestSpec{ + Params: []pipelinev1.Param{{ + Name: httpresolution.UrlParam, + Value: *pipelinev1.NewStructuredValues(params.url), + }}, + }, + } + if params.authSecret != "" { + s := params.authSecret + if s == emptyStr { + s = "" + } + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: httpresolution.HttpBasicAuthSecret, + Value: *pipelinev1.NewStructuredValues(s), + }) + } + + if params.authUsername != "" { + s := params.authUsername + if s == emptyStr { + s = "" + } + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: httpresolution.HttpBasicAuthUsername, + Value: *pipelinev1.NewStructuredValues(s), + }) + } + + if params.authSecretKey != "" { + rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ + Name: httpresolution.HttpBasicAuthSecretKey, + Value: *pipelinev1.NewStructuredValues(params.authSecretKey), + }) + } + + return rr +} diff --git a/pkg/remoteresolution/resolver/hub/resolver.go b/pkg/remoteresolution/resolver/hub/resolver.go new file mode 100644 index 00000000000..fbea8b32709 --- /dev/null +++ b/pkg/remoteresolution/resolver/hub/resolver.go @@ -0,0 +1,78 @@ +/* +Copyright 2024 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package hub + +import ( + "context" + + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" + "github.com/tektoncd/pipeline/pkg/resolution/common" + resolutionframework "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" + "github.com/tektoncd/pipeline/pkg/resolution/resolver/hub" +) + +const ( + // LabelValueHubResolverType is the value to use for the + // resolution.tekton.dev/type label on resource requests + LabelValueHubResolverType string = "hub" + + // ArtifactHubType is the value to use setting the type field to artifact + ArtifactHubType string = "artifact" + + // TektonHubType is the value to use setting the type field to tekton + TektonHubType string = "tekton" +) + +var _ framework.Resolver = &Resolver{} + +// Resolver implements a framework.Resolver that can fetch files from OCI bundles. +type Resolver struct { + // TektonHubURL is the URL for hub resolver with type tekton + TektonHubURL string + // ArtifactHubURL is the URL for hub resolver with type artifact + ArtifactHubURL string +} + +// Initialize sets up any dependencies needed by the resolver. None atm. +func (r *Resolver) Initialize(context.Context) error { + return nil +} + +// GetName returns a string name to refer to this resolver by. +func (r *Resolver) GetName(context.Context) string { + return "Hub" +} + +// GetConfigName returns the name of the bundle resolver's configmap. +func (r *Resolver) GetConfigName(context.Context) string { + return "hubresolver-config" +} + +// GetSelector returns a map of labels to match requests to this resolver. +func (r *Resolver) GetSelector(context.Context) map[string]string { + return map[string]string{ + common.LabelKeyResolverType: LabelValueHubResolverType, + } +} + +// Validate ensures parameters from a request are as expected. +func (r *Resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestSpec) error { + return hub.ValidateParams(ctx, req.Params, r.TektonHubURL) +} + +// Resolve uses the given params to resolve the requested file or resource. +func (r *Resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (resolutionframework.ResolvedResource, error) { + return hub.Resolve(ctx, req.Params, r.TektonHubURL, r.ArtifactHubURL) +} diff --git a/pkg/remoteresolution/resolver/hub/resolver_test.go b/pkg/remoteresolution/resolver/hub/resolver_test.go new file mode 100644 index 00000000000..bb5f7d19bff --- /dev/null +++ b/pkg/remoteresolution/resolver/hub/resolver_test.go @@ -0,0 +1,312 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package hub + +import ( + "context" + "errors" + "fmt" + "net/http" + "net/http/httptest" + "testing" + + "github.com/google/go-cmp/cmp" + pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + resolutionframework "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" + hubresolver "github.com/tektoncd/pipeline/pkg/resolution/resolver/hub" + "github.com/tektoncd/pipeline/test/diff" +) + +func TestGetSelector(t *testing.T) { + resolver := Resolver{} + sel := resolver.GetSelector(context.Background()) + if typ, has := sel[resolutioncommon.LabelKeyResolverType]; !has { + t.Fatalf("unexpected selector: %v", sel) + } else if typ != LabelValueHubResolverType { + t.Fatalf("unexpected type: %q", typ) + } +} + +func TestValidate(t *testing.T) { + testCases := []struct { + testName string + kind string + version string + catalog string + resourceName string + hubType string + expectedErr error + }{ + { + testName: "artifact type validation", + kind: "task", + resourceName: "foo", + version: "bar", + catalog: "baz", + hubType: ArtifactHubType, + }, { + testName: "tekton type validation", + kind: "task", + resourceName: "foo", + version: "bar", + catalog: "baz", + hubType: TektonHubType, + expectedErr: errors.New("failed to validate params: please configure TEKTON_HUB_API env variable to use tekton type"), + }, + } + + for _, tc := range testCases { + t.Run(tc.testName, func(t *testing.T) { + resolver := Resolver{} + params := map[string]string{ + hubresolver.ParamKind: tc.kind, + hubresolver.ParamName: tc.resourceName, + hubresolver.ParamVersion: tc.version, + hubresolver.ParamCatalog: tc.catalog, + hubresolver.ParamType: tc.hubType, + } + req := v1beta1.ResolutionRequestSpec{ + Params: toParams(params), + } + err := resolver.Validate(contextWithConfig(), &req) + if tc.expectedErr != nil { + checkExpectedErr(t, tc.expectedErr, err) + } else if err != nil { + t.Fatalf("unexpected error validating params: %v", err) + } + }) + } +} +func TestValidateMissing(t *testing.T) { + resolver := Resolver{} + + var err error + + paramsMissingName := map[string]string{ + hubresolver.ParamKind: "foo", + hubresolver.ParamVersion: "bar", + } + req := v1beta1.ResolutionRequestSpec{ + Params: toParams(paramsMissingName), + } + err = resolver.Validate(contextWithConfig(), &req) + if err == nil { + t.Fatalf("expected missing name err") + } + + paramsMissingVersion := map[string]string{ + hubresolver.ParamKind: "foo", + hubresolver.ParamName: "bar", + } + req = v1beta1.ResolutionRequestSpec{ + Params: toParams(paramsMissingVersion), + } + err = resolver.Validate(contextWithConfig(), &req) + + if err == nil { + t.Fatalf("expected missing version err") + } +} + +func TestValidateConflictingKindName(t *testing.T) { + testCases := []struct { + kind string + name string + version string + catalog string + hubType string + }{ + { + kind: "not-taskpipeline", + name: "foo", + version: "bar", + catalog: "baz", + hubType: TektonHubType, + }, + { + kind: "task", + name: "foo", + version: "bar", + catalog: "baz", + hubType: "not-tekton-artifact", + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + resolver := Resolver{} + params := map[string]string{ + hubresolver.ParamKind: tc.kind, + hubresolver.ParamName: tc.name, + hubresolver.ParamVersion: tc.version, + hubresolver.ParamCatalog: tc.catalog, + hubresolver.ParamType: tc.hubType, + } + req := v1beta1.ResolutionRequestSpec{ + Params: toParams(params), + } + err := resolver.Validate(contextWithConfig(), &req) + if err == nil { + t.Fatalf("expected err due to conflicting param") + } + }) + } +} + +func TestResolve(t *testing.T) { + testCases := []struct { + name string + kind string + imageName string + version string + catalog string + hubType string + input string + expectedRes []byte + expectedErr error + }{ + { + name: "valid response from Tekton Hub", + kind: "task", + imageName: "foo", + version: "baz", + catalog: "Tekton", + hubType: TektonHubType, + input: `{"data":{"yaml":"some content"}}`, + expectedRes: []byte("some content"), + }, + { + name: "valid response from Artifact Hub", + kind: "task", + imageName: "foo", + version: "baz", + catalog: "Tekton", + hubType: ArtifactHubType, + input: `{"data":{"manifestRaw":"some content"}}`, + expectedRes: []byte("some content"), + }, + { + name: "not-found response from hub", + kind: "task", + imageName: "foo", + version: "baz", + catalog: "Tekton", + hubType: TektonHubType, + input: `{"name":"not-found","id":"aaaaaaaa","message":"resource not found","temporary":false,"timeout":false,"fault":false}`, + expectedRes: []byte(""), + }, + { + name: "response with bad formatting error", + kind: "task", + imageName: "foo", + version: "baz", + catalog: "Tekton", + hubType: TektonHubType, + input: `value`, + expectedErr: errors.New("fail to fetch Tekton Hub resource: error unmarshalling json response: invalid character 'v' looking for beginning of value"), + }, + { + name: "response with empty body error from Tekton Hub", + kind: "task", + imageName: "foo", + version: "baz", + catalog: "Tekton", + hubType: TektonHubType, + expectedErr: errors.New("fail to fetch Tekton Hub resource: error unmarshalling json response: unexpected end of JSON input"), + }, + { + name: "response with empty body error from Artifact Hub", + kind: "task", + imageName: "foo", + version: "baz", + catalog: "Tekton", + hubType: ArtifactHubType, + expectedErr: errors.New("fail to fetch Artifact Hub resource: error unmarshalling json response: unexpected end of JSON input"), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + svr := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { + fmt.Fprintf(w, tc.input) + })) + + resolver := &Resolver{ + TektonHubURL: svr.URL, + ArtifactHubURL: svr.URL, + } + + params := map[string]string{ + hubresolver.ParamKind: tc.kind, + hubresolver.ParamName: tc.imageName, + hubresolver.ParamVersion: tc.version, + hubresolver.ParamCatalog: tc.catalog, + hubresolver.ParamType: tc.hubType, + } + req := v1beta1.ResolutionRequestSpec{ + Params: toParams(params), + } + output, err := resolver.Resolve(contextWithConfig(), &req) + if tc.expectedErr != nil { + checkExpectedErr(t, tc.expectedErr, err) + } else { + if err != nil { + t.Fatalf("unexpected error resolving: %v", err) + } + if d := cmp.Diff(tc.expectedRes, output.Data()); d != "" { + t.Errorf("unexpected resource from Resolve: %s", diff.PrintWantGot(d)) + } + } + }) + } +} + +func toParams(m map[string]string) []pipelinev1.Param { + var params []pipelinev1.Param + + for k, v := range m { + params = append(params, pipelinev1.Param{ + Name: k, + Value: *pipelinev1.NewStructuredValues(v), + }) + } + + return params +} + +func contextWithConfig() context.Context { + config := map[string]string{ + "default-tekton-hub-catalog": "Tekton", + "default-artifact-hub-task-catalog": "tekton-catalog-tasks", + "default-artifact-hub-pipeline-catalog": "tekton-catalog-pipelines", + "default-type": "artifact", + } + + return resolutionframework.InjectResolverConfigToContext(context.Background(), config) +} + +func checkExpectedErr(t *testing.T, expectedErr, actualErr error) { + t.Helper() + if actualErr == nil { + t.Fatalf("expected err '%v' but didn't get one", expectedErr) + } + if d := cmp.Diff(expectedErr.Error(), actualErr.Error()); d != "" { + t.Fatalf("expected err '%v' but got '%v'", expectedErr, actualErr) + } +} diff --git a/pkg/remoteresolution/resource/crd_resource.go b/pkg/remoteresolution/resource/crd_resource.go new file mode 100644 index 00000000000..017654ca005 --- /dev/null +++ b/pkg/remoteresolution/resource/crd_resource.go @@ -0,0 +1,92 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resource + +import ( + "context" + "errors" + + rrclient "github.com/tektoncd/pipeline/pkg/client/resolution/clientset/versioned" + rrlisters "github.com/tektoncd/pipeline/pkg/client/resolution/listers/resolution/v1beta1" + resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + resolutionresource "github.com/tektoncd/pipeline/pkg/resolution/resource" + apierrors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/apis" +) + +// CRDRequester implements the Requester interface using +// ResolutionRequest CRDs. +type CRDRequester struct { + clientset rrclient.Interface + lister rrlisters.ResolutionRequestLister +} + +// NewCRDRequester returns an implementation of Requester that uses +// ResolutionRequest CRD objects to mediate between the caller who wants a +// resource (e.g. Tekton Pipelines) and the responder who can fetch +// it (e.g. the gitresolver) +func NewCRDRequester(clientset rrclient.Interface, lister rrlisters.ResolutionRequestLister) *CRDRequester { + return &CRDRequester{clientset, lister} +} + +var _ Requester = &CRDRequester{} + +// Submit constructs a ResolutionRequest object and submits it to the +// kubernetes cluster, returning any errors experienced while doing so. +// If ResolutionRequest is succeeded then it returns the resolved data. +func (r *CRDRequester) Submit(ctx context.Context, resolver ResolverName, req Request) (ResolvedResource, error) { + rr, _ := r.lister.ResolutionRequests(req.ResolverPayload().Namespace).Get(req.ResolverPayload().Name) + if rr == nil { + if err := r.createResolutionRequest(ctx, resolver, req); err != nil && + // When the request reconciles frequently, the creation may fail + // because the list informer cache is not updated. + // If the request already exists then we can assume that is in progress. + // The next reconcile will handle it based on the actual situation. + !apierrors.IsAlreadyExists(err) { + return nil, err + } + return nil, resolutioncommon.ErrRequestInProgress + } + + if rr.Status.GetCondition(apis.ConditionSucceeded).IsUnknown() { + // TODO(sbwsg): This should be where an existing + // resource is given an additional owner reference so + // that it doesn't get deleted until the caller is done + // with it. Use appendOwnerReference and then submit + // update to ResolutionRequest. + return nil, resolutioncommon.ErrRequestInProgress + } + + if rr.Status.GetCondition(apis.ConditionSucceeded).IsTrue() { + return resolutionresource.CrdIntoResource(rr), nil + } + + message := rr.Status.GetCondition(apis.ConditionSucceeded).GetMessage() + err := resolutioncommon.NewError(resolutioncommon.ReasonResolutionFailed, errors.New(message)) + return nil, err +} + +func (r *CRDRequester) createResolutionRequest(ctx context.Context, resolver ResolverName, req Request) error { + var owner metav1.OwnerReference + if ownedReq, ok := req.(OwnedRequest); ok { + owner = ownedReq.OwnerRef() + } + rr := resolutionresource.CreateResolutionRequest(ctx, resolver, req.ResolverPayload().Name, req.ResolverPayload().Namespace, req.ResolverPayload().ResolutionSpec.Params, owner) + _, err := r.clientset.ResolutionV1beta1().ResolutionRequests(rr.Namespace).Create(ctx, rr, metav1.CreateOptions{}) + return err +} diff --git a/pkg/remoteresolution/resource/crd_resource_test.go b/pkg/remoteresolution/resource/crd_resource_test.go new file mode 100644 index 00000000000..6bc4150e67e --- /dev/null +++ b/pkg/remoteresolution/resource/crd_resource_test.go @@ -0,0 +1,324 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resource_test + +import ( + "context" + "encoding/base64" + "errors" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" + resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + "github.com/tektoncd/pipeline/test" + "github.com/tektoncd/pipeline/test/diff" + resolution "github.com/tektoncd/pipeline/test/remoteresolution" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/logging" + _ "knative.dev/pkg/system/testing" // Setup system.Namespace() + "sigs.k8s.io/yaml" +) + +// getCRDRequester returns an instance of the CRDRequester that has been seeded with +// d, where d represents the state of the system (existing resources) needed for the test. +func getCRDRequester(t *testing.T, d test.Data) (test.Assets, func()) { + t.Helper() + return initializeCRDRequesterAssets(t, d) +} + +func initializeCRDRequesterAssets(t *testing.T, d test.Data) (test.Assets, func()) { + t.Helper() + ctx, _ := ttesting.SetupFakeContext(t) + ctx, cancel := context.WithCancel(ctx) + c, informers := test.SeedTestData(t, ctx, d) + + return test.Assets{ + Logger: logging.FromContext(ctx), + Clients: c, + Informers: informers, + Ctx: ctx, + }, cancel +} + +func TestCRDRequesterSubmit(t *testing.T) { + ownerRef := mustParseOwnerReference(t, ` +apiVersion: tekton.dev/v1beta1 +blockOwnerDeletion: true +controller: true +kind: TaskRun +name: git-clone +uid: 727019c3-4066-4d8b-919e-90660dfd8b55 +`) + request := mustParseRawRequest(t, ` +resolverPayload: + name: git-ec247f5592afcaefa8485e34d2bd80c6 + namespace: namespace + resolutionSpec: + params: + - name: url + value: https://github.com/tektoncd/catalog + - name: revision + value: main + - name: pathInRepo + value: task/git-clone/0.6/git-clone.yaml +`) + baseRR := mustParseResolutionRequest(t, ` +kind: "ResolutionRequest" +apiVersion: "resolution.tekton.dev/v1beta1" +metadata: + name: "git-ec247f5592afcaefa8485e34d2bd80c6" + namespace: "namespace" + labels: + resolution.tekton.dev/type: "git" + ownerReferences: + - apiVersion: tekton.dev/v1beta1 + blockOwnerDeletion: true + controller: true + kind: TaskRun + name: git-clone + uid: 727019c3-4066-4d8b-919e-90660dfd8b55 +spec: + params: + - name: "url" + value: "https://github.com/tektoncd/catalog" + - name: "revision" + value: "main" + - name: "pathInRepo" + value: "task/git-clone/0.6/git-clone.yaml" +`) + createdRR := baseRR.DeepCopy() + // + unknownRR := baseRR.DeepCopy() + unknownRR.Status = *mustParseResolutionRequestStatus(t, ` +conditions: + - lastTransitionTime: "2023-03-26T10:31:29Z" + status: "Unknown" + type: Succeeded +`) + // + failedRR := baseRR.DeepCopy() + failedRR.Status = *mustParseResolutionRequestStatus(t, ` +conditions: + - lastTransitionTime: "2023-03-26T10:31:29Z" + status: "Failed" + type: Succeeded + message: "error message" +`) + // + successRR := baseRR.DeepCopy() + successRR.Status = *mustParseResolutionRequestStatus(t, ` +annotations: + resolution.tekton.dev/content-type: application/x-yaml + resolution.tekton.dev/path: task/git-clone/0.6/git-clone.yaml + resolution.tekton.dev/revision: main + resolution.tekton.dev/url: https://github.com/tektoncd/catalog +conditions: + - lastTransitionTime: "2023-03-26T10:31:29Z" + status: "True" + type: Succeeded + data: e30= +`) + // + successWithoutAnnotationsRR := baseRR.DeepCopy() + successWithoutAnnotationsRR.Status = *mustParseResolutionRequestStatus(t, ` +conditions: + - lastTransitionTime: "2023-03-26T10:31:29Z" + status: "True" + type: Succeeded + data: e30= +`) + + testCases := []struct { + name string + inputRequest *resolution.RawRequest + inputResolutionRequest *v1beta1.ResolutionRequest + expectedResolutionRequest *v1beta1.ResolutionRequest + expectedResolvedResource *v1beta1.ResolutionRequest + expectedErr error + }{ + { + name: "resolution request does not exist and needs to be created", + inputRequest: request, + inputResolutionRequest: nil, + expectedResolutionRequest: createdRR.DeepCopy(), + expectedResolvedResource: nil, + expectedErr: resolutioncommon.ErrRequestInProgress, + }, + { + name: "resolution request exist and status is unknown", + inputRequest: request, + inputResolutionRequest: unknownRR.DeepCopy(), + expectedResolutionRequest: nil, + expectedResolvedResource: nil, + expectedErr: resolutioncommon.ErrRequestInProgress, + }, + { + name: "resolution request exist and status is succeeded", + inputRequest: request, + inputResolutionRequest: successRR.DeepCopy(), + expectedResolutionRequest: nil, + expectedResolvedResource: successRR.DeepCopy(), + expectedErr: nil, + }, + { + name: "resolution request exist and status is succeeded but annotations is nil", + inputRequest: request, + inputResolutionRequest: successWithoutAnnotationsRR.DeepCopy(), + expectedResolutionRequest: nil, + expectedResolvedResource: successWithoutAnnotationsRR.DeepCopy(), + expectedErr: nil, + }, + { + name: "resolution request exist and status is failed", + inputRequest: request, + inputResolutionRequest: failedRR.DeepCopy(), + expectedResolutionRequest: nil, + expectedResolvedResource: nil, + expectedErr: resolutioncommon.NewError(resolutioncommon.ReasonResolutionFailed, errors.New("error message")), + }, + } + + for _, tc := range testCases { + t.Run(tc.name, func(t *testing.T) { + d := test.Data{} + if tc.inputResolutionRequest != nil { + d.ResolutionRequests = []*v1beta1.ResolutionRequest{tc.inputResolutionRequest} + } + + testAssets, cancel := getCRDRequester(t, d) + defer cancel() + ctx := testAssets.Ctx + clients := testAssets.Clients + + resolver := resolutioncommon.ResolverName("git") + crdRequester := resource.NewCRDRequester(clients.ResolutionRequests, testAssets.Informers.ResolutionRequest.Lister()) + requestWithOwner := &ownerRequest{ + Request: tc.inputRequest.Request(), + ownerRef: *ownerRef, + } + resolvedResource, err := crdRequester.Submit(ctx, resolver, requestWithOwner) + + // check the error + if err != nil || tc.expectedErr != nil { + if err == nil || tc.expectedErr == nil { + t.Errorf("expected error %v, but got %v", tc.expectedErr, err) + } else if err.Error() != tc.expectedErr.Error() { + t.Errorf("expected error %v, but got %v", tc.expectedErr, err) + } + } + + // check the resolved resource + switch { + case tc.expectedResolvedResource == nil: + // skipping check of resolved resources. + case tc.expectedResolvedResource != nil: + if resolvedResource == nil { + t.Errorf("expected resolved resource equal %v, but got %v", tc.expectedResolvedResource, resolvedResource) + break + } + rr := tc.expectedResolvedResource + data, err := base64.StdEncoding.Strict().DecodeString(rr.Status.Data) + if err != nil { + t.Errorf("unexpected error decoding expected resource data: %v", err) + } + expectedResolvedResource := resolution.NewResolvedResource(data, rr.Status.Annotations, rr.Status.RefSource, nil) + assertResolvedResourceEqual(t, expectedResolvedResource, resolvedResource) + } + + // check the resolution request + if tc.expectedResolutionRequest != nil { + resolutionrequest, err := clients.ResolutionRequests.ResolutionV1beta1(). + ResolutionRequests(tc.inputRequest.ResolverPayload.Namespace).Get(ctx, tc.inputRequest.ResolverPayload.Name, metav1.GetOptions{}) + if err != nil { + t.Errorf("unexpected error getting resource requests: %v", err) + } + if d := cmp.Diff(tc.expectedResolutionRequest, resolutionrequest); d != "" { + t.Errorf("expected resolution request to match %s", diff.PrintWantGot(d)) + } + } + }) + } +} + +type ownerRequest struct { + resource.Request + ownerRef metav1.OwnerReference +} + +func (r *ownerRequest) OwnerRef() metav1.OwnerReference { + return r.ownerRef +} + +func mustParseRawRequest(t *testing.T, yamlStr string) *resolution.RawRequest { + t.Helper() + output := &resolution.RawRequest{} + if err := yaml.Unmarshal([]byte(yamlStr), output); err != nil { + t.Errorf("parsing raw request %s: %v", yamlStr, err) + } + return output +} + +func mustParseOwnerReference(t *testing.T, yamlStr string) *metav1.OwnerReference { + t.Helper() + output := &metav1.OwnerReference{} + if err := yaml.Unmarshal([]byte(yamlStr), output); err != nil { + t.Errorf("parsing owner reference %s: %v", yamlStr, err) + } + return output +} + +func mustParseResolutionRequest(t *testing.T, yamlStr string) *v1beta1.ResolutionRequest { + t.Helper() + output := &v1beta1.ResolutionRequest{} + if err := yaml.Unmarshal([]byte(yamlStr), output); err != nil { + t.Errorf("parsing resolution request %s: %v", yamlStr, err) + } + return output +} + +func mustParseResolutionRequestStatus(t *testing.T, yamlStr string) *v1beta1.ResolutionRequestStatus { + t.Helper() + output := &v1beta1.ResolutionRequestStatus{} + if err := yaml.Unmarshal([]byte(yamlStr), output); err != nil { + t.Errorf("parsing resolution request status %s: %v", yamlStr, err) + } + return output +} + +func assertResolvedResourceEqual(t *testing.T, expected, actual resolutioncommon.ResolvedResource) { + t.Helper() + expectedBytes, err := expected.Data() + if err != nil { + t.Errorf("unexpected error getting expected resource data: %v", err) + } + actualBytes, err := actual.Data() + if err != nil { + t.Errorf("unexpected error getting acutal resource data: %v", err) + } + if d := cmp.Diff(expectedBytes, actualBytes); d != "" { + t.Errorf("expected resolved resource Data to match %s", diff.PrintWantGot(d)) + } + if d := cmp.Diff(expected.Annotations(), actual.Annotations()); d != "" { + t.Errorf("expected resolved resource Annotations to match %s", diff.PrintWantGot(d)) + } + if d := cmp.Diff(expected.RefSource(), actual.RefSource()); d != "" { + t.Errorf("expected resolved resource Source to match %s", diff.PrintWantGot(d)) + } +} diff --git a/pkg/remoteresolution/resource/doc.go b/pkg/remoteresolution/resource/doc.go new file mode 100644 index 00000000000..4f8393963da --- /dev/null +++ b/pkg/remoteresolution/resource/doc.go @@ -0,0 +1,24 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +/* +Package resource contains the upgraded remote resolution framework. +It is equivalent to `pkg/resolution/resource`. +This was necessary to ensure backwards compatibility with the existing framework. + +This package is subject to further refactoring and changes. +*/ +package resource diff --git a/pkg/remoteresolution/resource/request.go b/pkg/remoteresolution/resource/request.go new file mode 100644 index 00000000000..f5472b472fd --- /dev/null +++ b/pkg/remoteresolution/resource/request.go @@ -0,0 +1,83 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resource + +import ( + "context" + + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" +) + +type BasicRequest struct { + resolverPayload ResolverPayload +} + +var _ Request = &BasicRequest{} + +// NewRequest returns an instance of a BasicRequestV2 with the given resolverPayload. +func NewRequest(resolverPayload ResolverPayload) Request { + return &BasicRequest{resolverPayload} +} + +var _ Request = &BasicRequest{} + +// Params are the map of parameters associated with this request +func (req *BasicRequest) ResolverPayload() ResolverPayload { + return req.resolverPayload +} + +// Requester is the interface implemented by a type that knows how to +// submit requests for remote resources. +type Requester interface { + // Submit accepts the name of a resolver to submit a request to + // along with the request itself. + Submit(ctx context.Context, name ResolverName, req Request) (ResolvedResource, error) +} + +// Request is implemented by any type that represents a single request +// for a remote resource. Implementing this interface gives the underlying +// type an opportunity to control properties such as whether the name of +// a request has particular properties, whether the request should be made +// to a specific namespace, and precisely which parameters should be included. +type Request interface { + ResolverPayload() ResolverPayload +} + +// ResolverPayload is the struct which holds the payload to create +// the Resolution Request CRD. +type ResolverPayload struct { + Name string + Namespace string + ResolutionSpec *v1beta1.ResolutionRequestSpec +} + +// ResolutionRequester is the interface implemented by a type that knows how to +// submit requests for remote resources. +type ResolutionRequester interface { + // SubmitResolutionRequest accepts the name of a resolver to submit a request to + // along with the request itself. + SubmitResolutionRequest(ctx context.Context, name ResolverName, req RequestRemoteResource) (ResolvedResource, error) +} + +// RequestRemoteResource is implemented by any type that represents a single request +// for a remote resource. Implementing this interface gives the underlying +// type an opportunity to control properties such as whether the name of +// a request has particular properties, whether the request should be made +// to a specific namespace, and precisely which parameters should be included. +type RequestRemoteResource interface { + ResolverPayload() ResolverPayload +} diff --git a/pkg/remoteresolution/resource/request_test.go b/pkg/remoteresolution/resource/request_test.go new file mode 100644 index 00000000000..e387070345b --- /dev/null +++ b/pkg/remoteresolution/resource/request_test.go @@ -0,0 +1,73 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resource_test + +import ( + "testing" + + "github.com/google/go-cmp/cmp" + v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" + "github.com/tektoncd/pipeline/test/diff" +) + +func TestNewRequest(t *testing.T) { + type args struct { + resolverPayload resource.ResolverPayload + } + type want = args + golden := args{ + resolverPayload: resource.ResolverPayload{ + Name: "test-name", + Namespace: "test-namespace", + ResolutionSpec: &v1beta1.ResolutionRequestSpec{ + Params: v1.Params{ + {Name: "param1", Value: v1.ParamValue{Type: v1.ParamTypeString, StringVal: "value1"}}, + {Name: "param2", Value: v1.ParamValue{Type: v1.ParamTypeString, StringVal: "value2"}}, + }, + }, + }, + } + tests := []struct { + name string + args args + want want + }{ + { + name: "empty", + args: args{}, + want: want{}, + }, + { + name: "all", + args: golden, + want: golden, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + request := resource.NewRequest(tt.args.resolverPayload) + if request == nil { + t.Errorf("NewRequest() return nil") + } + if d := cmp.Diff(tt.want.resolverPayload, request.ResolverPayload()); d != "" { + t.Errorf("expected params to match %s", diff.PrintWantGot(d)) + } + }) + } +} diff --git a/pkg/remoteresolution/resource/resource.go b/pkg/remoteresolution/resource/resource.go new file mode 100644 index 00000000000..ff61f65b4fc --- /dev/null +++ b/pkg/remoteresolution/resource/resource.go @@ -0,0 +1,37 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package resource + +import ( + "github.com/tektoncd/pipeline/pkg/resolution/common" +) + +// This is an alias for avoiding cycle import + +// ResolverName is the type used for a resolver's name and is mostly +// used to ensure the function signatures that accept it are clear on the +// purpose for the given string. +type ResolverName = common.ResolverName + +// OwnedRequest is implemented by any type implementing Request that also needs +// to express a Kubernetes OwnerRef relationship as part of the request being +// made. +type OwnedRequest = common.OwnedRequest + +// ResolvedResource is implemented by any type that offers a read-only +// view of the data and metadata of a resolved remote resource. +type ResolvedResource = common.ResolvedResource diff --git a/pkg/resolution/resolver/bundle/resolver.go b/pkg/resolution/resolver/bundle/resolver.go index a5cd07ac5f3..b23b2f7a959 100644 --- a/pkg/resolution/resolver/bundle/resolver.go +++ b/pkg/resolution/resolver/bundle/resolver.go @@ -25,7 +25,9 @@ import ( 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" - "github.com/tektoncd/pipeline/pkg/resolution/common" + 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" "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" "k8s.io/client-go/kubernetes" "knative.dev/pkg/client/injection/kube/client" @@ -34,14 +36,14 @@ import ( const ( disabledError = "cannot handle resolution request, enable-bundles-resolver feature flag not true" - // LabelValueBundleResolverType is the value to use for the - // resolution.tekton.dev/type label on resource requests - LabelValueBundleResolverType string = "bundles" - // TODO(sbwsg): This should be exposed as a configurable option for // admins (e.g. via ConfigMap) timeoutDuration = time.Minute + // LabelValueBundleResolverType is the value to use for the + // resolution.tekton.dev/type label on resource requests + LabelValueBundleResolverType string = "bundles" + // BundleResolverName is the name that the bundle resolver should be associated with. BundleResolverName = "bundleresolver" ) @@ -76,21 +78,20 @@ 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 { - if r.isDisabled(ctx) { - return errors.New(disabledError) - } - if _, err := OptionsFromParams(ctx, params); err != nil { - return err - } - return nil + return ValidateParams(ctx, params) +} + +// Resolve uses the given params to resolve the requested file or resource. +func (r *Resolver) Resolve(ctx context.Context, params []v1.Param) (framework.ResolvedResource, error) { + return ResolveRequest(ctx, r.kubeClientSet, &v1beta1.ResolutionRequestSpec{Params: params}) } // 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) { - if r.isDisabled(ctx) { +func ResolveRequest(ctx context.Context, kubeClientSet kubernetes.Interface, req *v1beta1.ResolutionRequestSpec) (framework.ResolvedResource, error) { + if isDisabled(ctx) { return nil, errors.New(disabledError) } - opts, err := OptionsFromParams(ctx, params) + opts, err := OptionsFromParams(ctx, req.Params) if err != nil { return nil, err } @@ -99,7 +100,7 @@ func (r *Resolver) Resolve(ctx context.Context, params []pipelinev1.Param) (fram imagePullSecrets = append(imagePullSecrets, opts.ImagePullSecret) } namespace := common.RequestNamespace(ctx) - kc, err := k8schain.New(ctx, r.kubeClientSet, k8schain.Options{ + kc, err := k8schain.New(ctx, kubeClientSet, k8schain.Options{ Namespace: namespace, ImagePullSecrets: imagePullSecrets, ServiceAccountName: kauth.NoServiceAccount, @@ -112,7 +113,17 @@ func (r *Resolver) Resolve(ctx context.Context, params []pipelinev1.Param) (fram return GetEntry(ctx, kc, opts) } -func (r *Resolver) isDisabled(ctx context.Context) bool { +func ValidateParams(ctx context.Context, params []pipelinev1.Param) error { + if isDisabled(ctx) { + return errors.New(disabledError) + } + if _, err := OptionsFromParams(ctx, params); err != nil { + return err + } + return nil +} + +func isDisabled(ctx context.Context) bool { cfg := resolverconfig.FromContextOrDefaults(ctx) return !cfg.FeatureFlags.EnableBundleResolver } diff --git a/pkg/resolution/resolver/bundle/resolver_test.go b/pkg/resolution/resolver/bundle/resolver_test.go index 4f575d00b8f..2cdc8571631 100644 --- a/pkg/resolution/resolver/bundle/resolver_test.go +++ b/pkg/resolution/resolver/bundle/resolver_test.go @@ -32,11 +32,11 @@ import ( pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/internal/resolution" ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" - resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + common "github.com/tektoncd/pipeline/pkg/resolution/common" bundle "github.com/tektoncd/pipeline/pkg/resolution/resolver/bundle" frtesting "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework/testing" - "github.com/tektoncd/pipeline/pkg/resolution/resolver/internal" "github.com/tektoncd/pipeline/test" "github.com/tektoncd/pipeline/test/diff" corev1 "k8s.io/api/core/v1" @@ -56,7 +56,7 @@ const ( func TestGetSelector(t *testing.T) { resolver := bundle.Resolver{} sel := resolver.GetSelector(context.Background()) - if typ, has := sel[resolutioncommon.LabelKeyResolverType]; !has { + if typ, has := sel[common.LabelKeyResolverType]; !has { t.Fatalf("unexpected selector: %v", sel) } else if typ != bundle.LabelValueBundleResolverType { t.Fatalf("unexpected type: %q", typ) @@ -347,7 +347,7 @@ func TestResolve(t *testing.T) { kind: "task", }, imageName: "single-task", - expectedStatus: internal.CreateResolutionRequestStatusWithData(taskAsYAML), + expectedStatus: resolution.CreateResolutionRequestStatusWithData(taskAsYAML), }, { name: "single task: param kind is capitalized, but kind in bundle is not", args: ¶ms{ @@ -357,7 +357,7 @@ func TestResolve(t *testing.T) { }, kindInBundle: "task", imageName: "single-task", - expectedStatus: internal.CreateResolutionRequestStatusWithData(taskAsYAML), + expectedStatus: resolution.CreateResolutionRequestStatusWithData(taskAsYAML), }, { name: "single task: tag is included in the bundle parameter", args: ¶ms{ @@ -366,7 +366,7 @@ func TestResolve(t *testing.T) { kind: "task", }, imageName: "single-task", - expectedStatus: internal.CreateResolutionRequestStatusWithData(taskAsYAML), + expectedStatus: resolution.CreateResolutionRequestStatusWithData(taskAsYAML), }, { name: "single task: using default kind value from configmap", args: ¶ms{ @@ -374,7 +374,7 @@ func TestResolve(t *testing.T) { name: "example-task", }, imageName: "single-task", - expectedStatus: internal.CreateResolutionRequestStatusWithData(taskAsYAML), + expectedStatus: resolution.CreateResolutionRequestStatusWithData(taskAsYAML), }, { name: "single pipeline", args: ¶ms{ @@ -383,7 +383,7 @@ func TestResolve(t *testing.T) { kind: "pipeline", }, imageName: "single-pipeline", - expectedStatus: internal.CreateResolutionRequestStatusWithData(pipelineAsYAML), + expectedStatus: resolution.CreateResolutionRequestStatusWithData(pipelineAsYAML), }, { name: "multiple resources: an image has both task and pipeline resource", args: ¶ms{ @@ -392,7 +392,7 @@ func TestResolve(t *testing.T) { kind: "pipeline", }, imageName: "multiple-resources", - expectedStatus: internal.CreateResolutionRequestStatusWithData(pipelineAsYAML), + expectedStatus: resolution.CreateResolutionRequestStatusWithData(pipelineAsYAML), }, { name: "too many objects in an image", args: ¶ms{ @@ -400,7 +400,7 @@ func TestResolve(t *testing.T) { name: "2-task", kind: "task", }, - expectedStatus: internal.CreateResolutionRequestFailureStatus(), + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), expectedErrMessage: fmt.Sprintf("contained more than the maximum %d allow objects", bundle.MaximumBundleObjects), }, { name: "single task no version", @@ -409,7 +409,7 @@ func TestResolve(t *testing.T) { name: "foo", kind: "task", }, - expectedStatus: internal.CreateResolutionRequestFailureStatus(), + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), expectedErrMessage: fmt.Sprintf("the layer 0 does not contain a %s annotation", bundle.BundleAnnotationAPIVersion), }, { name: "single task no kind", @@ -418,7 +418,7 @@ func TestResolve(t *testing.T) { name: "foo", kind: "task", }, - expectedStatus: internal.CreateResolutionRequestFailureStatus(), + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), expectedErrMessage: fmt.Sprintf("the layer 0 does not contain a %s annotation", bundle.BundleAnnotationKind), }, { name: "single task no name", @@ -427,7 +427,7 @@ func TestResolve(t *testing.T) { name: "foo", kind: "task", }, - expectedStatus: internal.CreateResolutionRequestFailureStatus(), + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), expectedErrMessage: fmt.Sprintf("the layer 0 does not contain a %s annotation", bundle.BundleAnnotationName), }, { name: "single task kind incorrect form", @@ -436,7 +436,7 @@ func TestResolve(t *testing.T) { name: "foo", kind: "task", }, - expectedStatus: internal.CreateResolutionRequestFailureStatus(), + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), expectedErrMessage: fmt.Sprintf("the layer 0 the annotation %s must be lowercased and singular, found %s", bundle.BundleAnnotationKind, "Task"), }, } @@ -521,7 +521,7 @@ func createRequest(p *params) *v1beta1.ResolutionRequest { Namespace: "foo", CreationTimestamp: metav1.Time{Time: time.Now()}, Labels: map[string]string{ - resolutioncommon.LabelKeyResolverType: bundle.LabelValueBundleResolverType, + common.LabelKeyResolverType: bundle.LabelValueBundleResolverType, }, }, Spec: v1beta1.ResolutionRequestSpec{ @@ -544,7 +544,7 @@ func createRequest(p *params) *v1beta1.ResolutionRequest { } func createError(image, msg string) error { - return &resolutioncommon.GetResourceError{ + return &common.GetResourceError{ ResolverName: bundle.BundleResolverName, Key: "foo/rr", Original: fmt.Errorf("invalid tekton bundle %s, error: %s", image, msg), diff --git a/pkg/resolution/resolver/cluster/resolver.go b/pkg/resolution/resolver/cluster/resolver.go index 6483016b93b..f3781cbef33 100644 --- a/pkg/resolution/resolver/cluster/resolver.go +++ b/pkg/resolution/resolver/cluster/resolver.go @@ -27,7 +27,7 @@ import ( pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" clientset "github.com/tektoncd/pipeline/pkg/client/clientset/versioned" pipelineclient "github.com/tektoncd/pipeline/pkg/client/injection/client" - resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + common "github.com/tektoncd/pipeline/pkg/resolution/common" "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/pkg/logging" @@ -71,25 +71,24 @@ func (r *Resolver) GetName(_ context.Context) string { // the cluster resolver to process them. func (r *Resolver) GetSelector(_ context.Context) map[string]string { return map[string]string{ - resolutioncommon.LabelKeyResolverType: LabelValueClusterResolverType, + common.LabelKeyResolverType: LabelValueClusterResolverType, } } // ValidateParams returns an error if the given parameter map is not // valid for a resource request targeting the cluster resolver. func (r *Resolver) ValidateParams(ctx context.Context, params []pipelinev1.Param) error { - if r.isDisabled(ctx) { - return errors.New(disabledError) - } - - _, err := populateParamsWithDefaults(ctx, params) - return err + return ValidateParams(ctx, params) } // Resolve performs the work of fetching a resource from a namespace with the given // parameters. func (r *Resolver) Resolve(ctx context.Context, origParams []pipelinev1.Param) (framework.ResolvedResource, error) { - if r.isDisabled(ctx) { + return ResolveFromParams(ctx, origParams, r.pipelineClientSet) +} + +func ResolveFromParams(ctx context.Context, origParams []pipelinev1.Param, pipelineClientSet clientset.Interface) (framework.ResolvedResource, error) { + if isDisabled(ctx) { return nil, errors.New(disabledError) } @@ -109,52 +108,23 @@ func (r *Resolver) Resolve(ctx context.Context, origParams []pipelinev1.Param) ( switch params[KindParam] { case "task": - task, err := r.pipelineClientSet.TektonV1().Tasks(params[NamespaceParam]).Get(ctx, params[NameParam], metav1.GetOptions{}) + task, err := pipelineClientSet.TektonV1().Tasks(params[NamespaceParam]).Get(ctx, params[NameParam], metav1.GetOptions{}) if err != nil { logger.Infof("failed to load task %s from namespace %s: %v", params[NameParam], params[NamespaceParam], err) return nil, err } - uid = string(task.UID) - task.Kind = "Task" - task.APIVersion = groupVersion - data, err = yaml.Marshal(task) - if err != nil { - logger.Infof("failed to marshal task %s from namespace %s: %v", params[NameParam], params[NamespaceParam], err) - return nil, err - } - sha256Checksum, err = task.Checksum() - if err != nil { - return nil, err - } - - spec, err = yaml.Marshal(task.Spec) + uid, data, sha256Checksum, spec, err = fetchTask(ctx, groupVersion, task, params) if err != nil { - logger.Infof("failed to marshal the spec of the task %s from namespace %s: %v", params[NameParam], params[NamespaceParam], err) return nil, err } case "pipeline": - pipeline, err := r.pipelineClientSet.TektonV1().Pipelines(params[NamespaceParam]).Get(ctx, params[NameParam], metav1.GetOptions{}) + pipeline, err := pipelineClientSet.TektonV1().Pipelines(params[NamespaceParam]).Get(ctx, params[NameParam], metav1.GetOptions{}) if err != nil { logger.Infof("failed to load pipeline %s from namespace %s: %v", params[NameParam], params[NamespaceParam], err) return nil, err } - uid = string(pipeline.UID) - pipeline.Kind = "Pipeline" - pipeline.APIVersion = groupVersion - data, err = yaml.Marshal(pipeline) + uid, data, sha256Checksum, spec, err = fetchPipeline(ctx, groupVersion, pipeline, params) if err != nil { - logger.Infof("failed to marshal pipeline %s from namespace %s: %v", params[NameParam], params[NamespaceParam], err) - return nil, err - } - - sha256Checksum, err = pipeline.Checksum() - if err != nil { - return nil, err - } - - spec, err = yaml.Marshal(pipeline.Spec) - if err != nil { - logger.Infof("failed to marshal the spec of the pipeline %s from namespace %s: %v", params[NameParam], params[NamespaceParam], err) return nil, err } default: @@ -179,11 +149,6 @@ func (r *Resolver) GetConfigName(context.Context) string { return configMapName } -func (r *Resolver) isDisabled(ctx context.Context) bool { - cfg := resolverconfig.FromContextOrDefaults(ctx) - return !cfg.FeatureFlags.EnableClusterResolver -} - // ResolvedClusterResource implements framework.ResolvedResource and returns // the resolved file []byte data and an annotation map for any metadata. type ResolvedClusterResource struct { @@ -302,3 +267,62 @@ func isInCommaSeparatedList(checkVal string, commaList string) bool { } return false } +func isDisabled(ctx context.Context) bool { + cfg := resolverconfig.FromContextOrDefaults(ctx) + return !cfg.FeatureFlags.EnableClusterResolver +} + +func ValidateParams(ctx context.Context, params []pipelinev1.Param) error { + if isDisabled(ctx) { + return errors.New(disabledError) + } + + _, err := populateParamsWithDefaults(ctx, params) + return err +} + +func fetchTask(ctx context.Context, groupVersion string, task *pipelinev1.Task, params map[string]string) (string, []byte, []byte, []byte, error) { + logger := logging.FromContext(ctx) + uid := string(task.UID) + task.Kind = "Task" + task.APIVersion = groupVersion + data, err := yaml.Marshal(task) + if err != nil { + logger.Infof("failed to marshal task %s from namespace %s: %v", params[NameParam], params[NamespaceParam], err) + return "", nil, nil, nil, err + } + sha256Checksum, err := task.Checksum() + if err != nil { + return "", nil, nil, nil, err + } + + spec, err := yaml.Marshal(task.Spec) + if err != nil { + logger.Infof("failed to marshal the spec of the task %s from namespace %s: %v", params[NameParam], params[NamespaceParam], err) + return "", nil, nil, nil, err + } + return uid, data, sha256Checksum, spec, nil +} +func fetchPipeline(ctx context.Context, groupVersion string, pipeline *pipelinev1.Pipeline, params map[string]string) (string, []byte, []byte, []byte, error) { + logger := logging.FromContext(ctx) + uid := string(pipeline.UID) + pipeline.Kind = "Pipeline" + pipeline.APIVersion = groupVersion + data, err := yaml.Marshal(pipeline) + if err != nil { + logger.Infof("failed to marshal pipeline %s from namespace %s: %v", params[NameParam], params[NamespaceParam], err) + return "", nil, nil, nil, err + } + + sha256Checksum, err := pipeline.Checksum() + if err != nil { + return "", nil, nil, nil, err + } + + spec, err := yaml.Marshal(pipeline.Spec) + if err != nil { + logger.Infof("failed to marshal the spec of the pipeline %s from namespace %s: %v", params[NameParam], params[NamespaceParam], err) + return "", nil, nil, nil, err + } + return uid, data, sha256Checksum, spec, nil +} diff --git a/pkg/resolution/resolver/cluster/resolver_test.go b/pkg/resolution/resolver/cluster/resolver_test.go index e1051a7089d..6cfdf36ac70 100644 --- a/pkg/resolution/resolver/cluster/resolver_test.go +++ b/pkg/resolution/resolver/cluster/resolver_test.go @@ -30,12 +30,12 @@ import ( pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/internal/resolution" ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" - resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + common "github.com/tektoncd/pipeline/pkg/resolution/common" cluster "github.com/tektoncd/pipeline/pkg/resolution/resolver/cluster" "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" frtesting "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework/testing" - "github.com/tektoncd/pipeline/pkg/resolution/resolver/internal" "github.com/tektoncd/pipeline/test" "github.com/tektoncd/pipeline/test/diff" corev1 "k8s.io/api/core/v1" @@ -53,7 +53,7 @@ const ( func TestGetSelector(t *testing.T) { resolver := cluster.Resolver{} sel := resolver.GetSelector(context.Background()) - if typ, has := sel[resolutioncommon.LabelKeyResolverType]; !has { + if typ, has := sel[common.LabelKeyResolverType]; !has { t.Fatalf("unexpected selector: %v", sel) } else if typ != cluster.LabelValueClusterResolverType { t.Fatalf("unexpected type: %q", typ) @@ -360,8 +360,8 @@ func TestResolve(t *testing.T) { kind: "task", resourceName: exampleTask.Name, namespace: "other-ns", - expectedStatus: internal.CreateResolutionRequestFailureStatus(), - expectedErr: &resolutioncommon.GetResourceError{ + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErr: &common.GetResourceError{ ResolverName: cluster.ClusterResolverName, Key: "foo/rr", Original: errors.New(`tasks.tekton.dev "example-task" not found`), @@ -372,8 +372,8 @@ func TestResolve(t *testing.T) { resourceName: exampleTask.Name, namespace: "other-ns", allowedNamespaces: "foo,bar", - expectedStatus: internal.CreateResolutionRequestFailureStatus(), - expectedErr: &resolutioncommon.InvalidRequestError{ + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErr: &common.InvalidRequestError{ ResolutionRequestKey: "foo/rr", Message: "access to specified namespace other-ns is not allowed", }, @@ -383,8 +383,8 @@ func TestResolve(t *testing.T) { resourceName: exampleTask.Name, namespace: "other-ns", blockedNamespaces: "foo,other-ns,bar", - expectedStatus: internal.CreateResolutionRequestFailureStatus(), - expectedErr: &resolutioncommon.InvalidRequestError{ + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), + expectedErr: &common.InvalidRequestError{ ResolutionRequestKey: "foo/rr", Message: "access to specified namespace other-ns is blocked", }, @@ -471,7 +471,7 @@ func createRequest(kind, name, namespace string) *v1beta1.ResolutionRequest { Namespace: "foo", CreationTimestamp: metav1.Time{Time: time.Now()}, Labels: map[string]string{ - resolutioncommon.LabelKeyResolverType: cluster.LabelValueClusterResolverType, + common.LabelKeyResolverType: cluster.LabelValueClusterResolverType, }, }, Spec: v1beta1.ResolutionRequestSpec{ diff --git a/pkg/resolution/resolver/framework/controller.go b/pkg/resolution/resolver/framework/controller.go index f1d270a398a..61bc3c04626 100644 --- a/pkg/resolution/resolver/framework/controller.go +++ b/pkg/resolution/resolver/framework/controller.go @@ -46,7 +46,7 @@ type ReconcilerModifier = func(reconciler *Reconciler) // This sets up a lot of the boilerplate that individual resolvers // shouldn't need to be concerned with since it's common to all of them. func NewController(ctx context.Context, resolver Resolver, modifiers ...ReconcilerModifier) func(context.Context, configmap.Watcher) *controller.Impl { - if err := validateResolver(ctx, resolver); err != nil { + if err := ValidateResolver(ctx, resolver.GetSelector(ctx)); err != nil { panic(err.Error()) } return func(ctx context.Context, cmw configmap.Watcher) *controller.Impl { @@ -60,7 +60,7 @@ func NewController(ctx context.Context, resolver Resolver, modifiers ...Reconcil } r := &Reconciler{ - LeaderAwareFuncs: leaderAwareFuncs(rrInformer.Lister()), + LeaderAwareFuncs: LeaderAwareFuncs(rrInformer.Lister()), kubeClientSet: kubeclientset, resolutionRequestLister: rrInformer.Lister(), resolutionRequestClientSet: rrclientset, @@ -82,7 +82,7 @@ func NewController(ctx context.Context, resolver Resolver, modifiers ...Reconcil }) _, err := rrInformer.Informer().AddEventHandler(cache.FilteringResourceEventHandler{ - FilterFunc: filterResolutionRequestsBySelector(resolver.GetSelector(ctx)), + FilterFunc: FilterResolutionRequestsBySelector(resolver.GetSelector(ctx)), Handler: cache.ResourceEventHandlerFuncs{ AddFunc: impl.Enqueue, UpdateFunc: func(oldObj, newObj interface{}) { @@ -101,7 +101,35 @@ func NewController(ctx context.Context, resolver Resolver, modifiers ...Reconcil } } -func filterResolutionRequestsBySelector(selector map[string]string) func(obj interface{}) bool { +// watchConfigChanges binds a framework.Resolver to updates on its +// configmap, using knative's configmap helpers. This is only done if +// the resolver implements the framework.ConfigWatcher interface. +func watchConfigChanges(ctx context.Context, reconciler *Reconciler, cmw configmap.Watcher) { + if configWatcher, ok := reconciler.resolver.(ConfigWatcher); ok { + logger := logging.FromContext(ctx) + resolverConfigName := configWatcher.GetConfigName(ctx) + if resolverConfigName == "" { + panic("resolver returned empty config name") + } + reconciler.configStore = NewConfigStore(resolverConfigName, logger) + reconciler.configStore.WatchConfigs(cmw) + } +} + +// applyModifiersAndDefaults applies the given modifiers to +// a reconciler and, after doing so, sets any default values for things +// that weren't set by a modifier. +func applyModifiersAndDefaults(ctx context.Context, r *Reconciler, modifiers []ReconcilerModifier) { + for _, mod := range modifiers { + mod(r) + } + + if r.Clock == nil { + r.Clock = clock.RealClock{} + } +} + +func FilterResolutionRequestsBySelector(selector map[string]string) func(obj interface{}) bool { return func(obj interface{}) bool { rr, ok := obj.(*v1beta1.ResolutionRequest) if !ok { @@ -127,7 +155,7 @@ func filterResolutionRequestsBySelector(selector map[string]string) func(obj int // fact that the controller crashes if they're missing. It looks // like this is bucketing based on labels. Should we use the filter // selector from above in the call to lister.List here? -func leaderAwareFuncs(lister rrlister.ResolutionRequestLister) reconciler.LeaderAwareFuncs { +func LeaderAwareFuncs(lister rrlister.ResolutionRequestLister) reconciler.LeaderAwareFuncs { return reconciler.LeaderAwareFuncs{ PromoteFunc: func(bkt reconciler.Bucket, enq func(reconciler.Bucket, types.NamespacedName)) error { all, err := lister.List(labels.Everything()) @@ -156,8 +184,7 @@ var ( ErrorMissingTypeSelector = ErrMissingTypeSelector ) -func validateResolver(ctx context.Context, r Resolver) error { - sel := r.GetSelector(ctx) +func ValidateResolver(ctx context.Context, sel map[string]string) error { if sel == nil { return ErrMissingTypeSelector } @@ -166,31 +193,3 @@ func validateResolver(ctx context.Context, r Resolver) error { } return nil } - -// watchConfigChanges binds a framework.Resolver to updates on its -// configmap, using knative's configmap helpers. This is only done if -// the resolver implements the framework.ConfigWatcher interface. -func watchConfigChanges(ctx context.Context, reconciler *Reconciler, cmw configmap.Watcher) { - if configWatcher, ok := reconciler.resolver.(ConfigWatcher); ok { - logger := logging.FromContext(ctx) - resolverConfigName := configWatcher.GetConfigName(ctx) - if resolverConfigName == "" { - panic("resolver returned empty config name") - } - reconciler.configStore = NewConfigStore(resolverConfigName, logger) - reconciler.configStore.WatchConfigs(cmw) - } -} - -// applyModifiersAndDefaults applies the given modifiers to -// a reconciler and, after doing so, sets any default values for things -// that weren't set by a modifier. -func applyModifiersAndDefaults(ctx context.Context, r *Reconciler, modifiers []ReconcilerModifier) { - for _, mod := range modifiers { - mod(r) - } - - if r.Clock == nil { - r.Clock = clock.RealClock{} - } -} diff --git a/pkg/resolution/resolver/framework/fakeresolver.go b/pkg/resolution/resolver/framework/fakeresolver.go index 0943199601b..3fd363f825c 100644 --- a/pkg/resolution/resolver/framework/fakeresolver.go +++ b/pkg/resolution/resolver/framework/fakeresolver.go @@ -103,6 +103,10 @@ func (r *FakeResolver) GetSelector(_ context.Context) map[string]string { // ValidateParams returns an error if the given parameter map is not // valid for a resource request targeting the fake resolver. func (r *FakeResolver) ValidateParams(_ context.Context, params []pipelinev1.Param) error { + return ValidateParams(params) +} + +func ValidateParams(params []pipelinev1.Param) error { paramsMap := make(map[string]pipelinev1.ParamValue) for _, p := range params { paramsMap[p.Name] = p.Value @@ -132,6 +136,10 @@ func (r *FakeResolver) ValidateParams(_ context.Context, params []pipelinev1.Par // Resolve performs the work of fetching a file from the fake resolver given a map of // parameters. func (r *FakeResolver) Resolve(_ context.Context, params []pipelinev1.Param) (ResolvedResource, error) { + return Resolve(params, r.ForParam) +} + +func Resolve(params []pipelinev1.Param, forParam map[string]*FakeResolvedResource) (ResolvedResource, error) { paramsMap := make(map[string]pipelinev1.ParamValue) for _, p := range params { paramsMap[p.Name] = p.Value @@ -139,7 +147,7 @@ func (r *FakeResolver) Resolve(_ context.Context, params []pipelinev1.Param) (Re paramValue := paramsMap[FakeParamName].StringVal - frr, ok := r.ForParam[paramValue] + frr, ok := forParam[paramValue] if !ok { return nil, fmt.Errorf("couldn't find resource for param value %s", paramValue) } @@ -159,8 +167,13 @@ var _ TimedResolution = &FakeResolver{} // GetResolutionTimeout returns the configured timeout for the reconciler, or the default time.Duration if not configured. func (r *FakeResolver) GetResolutionTimeout(ctx context.Context, defaultTimeout time.Duration) time.Duration { - if r.Timeout > 0 { - return r.Timeout + return GetResolutionTimeout(r.Timeout, defaultTimeout) +} + +// GetResolutionTimeout returns the input timeout if set to something greater than 0 or the default time.Duration if not configured. +func GetResolutionTimeout(timeout, defaultTimeout time.Duration) time.Duration { + if timeout > 0 { + return timeout } return defaultTimeout } diff --git a/pkg/resolution/resolver/git/config.go b/pkg/resolution/resolver/git/config.go index a085bdfac39..44645b1fae6 100644 --- a/pkg/resolution/resolver/git/config.go +++ b/pkg/resolution/resolver/git/config.go @@ -17,20 +17,20 @@ limitations under the License. package git const ( - // defaultTimeoutKey is the configuration field name for controlling + // DefaultTimeoutKey is the configuration field name for controlling // the maximum duration of a resolution request for a file from git. - defaultTimeoutKey = "fetch-timeout" + DefaultTimeoutKey = "fetch-timeout" - // defaultURLKey is the configuration field name for controlling + // DefaultURLKey is the configuration field name for controlling // the git url to fetch the remote resource from. - defaultURLKey = "default-url" + DefaultURLKey = "default-url" - // defaultRevisionKey is the configuration field name for controlling + // DefaultRevisionKey is the configuration field name for controlling // the revision to fetch the remote resource from. - defaultRevisionKey = "default-revision" + DefaultRevisionKey = "default-revision" - // defaultOrgKey is the configuration field name for setting a default organization when using the SCM API. - defaultOrgKey = "default-org" + // DefaultOrgKey is the configuration field name for setting a default organization when using the SCM API. + DefaultOrgKey = "default-org" // ServerURLKey is the config map key for the SCM provider URL ServerURLKey = "server-url" diff --git a/pkg/resolution/resolver/git/params.go b/pkg/resolution/resolver/git/params.go index 679d0b0e9f5..9ca9248a4f4 100644 --- a/pkg/resolution/resolver/git/params.go +++ b/pkg/resolution/resolver/git/params.go @@ -17,24 +17,24 @@ limitations under the License. package git const ( - // urlParam is the git repo url when using the anonymous/full clone approach - urlParam string = "url" - // orgParam is the organization to find the repository in when using the SCM API approach - orgParam = "org" - // repoParam is the repository to use when using the SCM API approach - repoParam = "repo" - // pathParam is the pathInRepo into the git repo where a file is located. This is used with both approaches. - pathParam string = "pathInRepo" - // revisionParam is the git revision that a file should be fetched from. This is used with both approaches. - revisionParam string = "revision" - // tokenParam is an optional reference to a secret name for SCM API authentication - tokenParam string = "token" - // tokenKeyParam is an optional reference to a key in the tokenParam secret for SCM API authentication - tokenKeyParam string = "tokenKey" - // defaultTokenKeyParam is the default key in the tokenParam secret for SCM API authentication - defaultTokenKeyParam string = "token" - // scmTypeParams is an optional string overriding the scm-type configuration (ie: github, gitea, gitlab etc..) - scmTypeParam string = "scmType" - // serverURLParams is an optional string to the server URL for the SCM API to connect to - serverURLParam string = "serverURL" + // UrlParam is the git repo Url when using the anonymous/full clone approach + UrlParam string = "url" + // OrgParam is the organization to find the repository in when using the SCM API approach + OrgParam = "org" + // RepoParam is the repository to use when using the SCM API approach + RepoParam = "repo" + // PathParam is the pathInRepo into the git repo where a file is located. This is used with both approaches. + PathParam string = "pathInRepo" + // RevisionParam is the git revision that a file should be fetched from. This is used with both approaches. + RevisionParam string = "revision" + // TokenParam is an optional reference to a secret name for SCM API authentication + TokenParam string = "token" + // TokenKeyParam is an optional reference to a key in the TokenParam secret for SCM API authentication + TokenKeyParam string = "tokenKey" + // DefaultTokenKeyParam is the default key in the TokenParam secret for SCM API authentication + DefaultTokenKeyParam string = "token" + // scmTypeParam is an optional string overriding the scm-type configuration (ie: github, gitea, gitlab etc..) + ScmTypeParam string = "scmType" + // serverURLParam is an optional string to the server URL for the SCM API to connect to + ServerURLParam string = "serverURL" ) diff --git a/pkg/resolution/resolver/git/resolver.go b/pkg/resolution/resolver/git/resolver.go index 34fcd6ad18f..c8294de862f 100644 --- a/pkg/resolution/resolver/git/resolver.go +++ b/pkg/resolution/resolver/git/resolver.go @@ -36,8 +36,7 @@ import ( "github.com/jenkins-x/go-scm/scm/factory" resolverconfig "github.com/tektoncd/pipeline/pkg/apis/config/resolver" pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" - "github.com/tektoncd/pipeline/pkg/resolution/common" - resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + common "github.com/tektoncd/pipeline/pkg/resolution/common" "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" "go.uber.org/zap" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -106,41 +105,45 @@ func (r *Resolver) GetName(_ context.Context) string { // the gitresolver to process them. func (r *Resolver) GetSelector(_ context.Context) map[string]string { return map[string]string{ - resolutioncommon.LabelKeyResolverType: labelValueGitResolverType, + common.LabelKeyResolverType: labelValueGitResolverType, } } // ValidateParams returns an error if the given parameter map is not // valid for a resource request targeting the gitresolver. func (r *Resolver) ValidateParams(ctx context.Context, params []pipelinev1.Param) error { - if r.isDisabled(ctx) { - return errors.New(disabledError) - } - - _, err := populateDefaultParams(ctx, params) - if err != nil { - return err - } - return nil + return ValidateParams(ctx, params) } // Resolve performs the work of fetching a file from git given a map of // parameters. func (r *Resolver) Resolve(ctx context.Context, origParams []pipelinev1.Param) (framework.ResolvedResource, error) { - if r.isDisabled(ctx) { + if IsDisabled(ctx) { return nil, errors.New(disabledError) } - params, err := populateDefaultParams(ctx, origParams) + params, err := PopulateDefaultParams(ctx, origParams) if err != nil { return nil, err } - if params[urlParam] != "" { - return r.resolveAnonymousGit(ctx, params) + if params[UrlParam] != "" { + return ResolveAnonymousGit(ctx, params) } - return r.resolveAPIGit(ctx, params) + return ResolveAPIGit(ctx, params, r.kubeClient, r.logger, r.cache, r.ttl, r.clientFunc) +} + +func ValidateParams(ctx context.Context, params []pipelinev1.Param) error { + if IsDisabled(ctx) { + return errors.New(disabledError) + } + + _, err := PopulateDefaultParams(ctx, params) + if err != nil { + return err + } + return nil } // validateRepoURL validates if the given URL is a valid git, http, https URL or @@ -152,81 +155,19 @@ func validateRepoURL(url string) bool { return re.MatchString(url) } -func (r *Resolver) resolveAPIGit(ctx context.Context, params map[string]string) (framework.ResolvedResource, error) { - // If we got here, the "repo" param was specified, so use the API approach - scmType, serverURL, err := r.getSCMTypeAndServerURL(ctx, params) - if err != nil { - return nil, err - } - secretRef := &secretCacheKey{ - name: params[tokenParam], - key: params[tokenKeyParam], - } - if secretRef.name != "" { - if secretRef.key == "" { - secretRef.key = defaultTokenKeyParam - } - secretRef.ns = common.RequestNamespace(ctx) - } else { - secretRef = nil - } - apiToken, err := r.getAPIToken(ctx, secretRef) - if err != nil { - return nil, err - } - scmClient, err := r.clientFunc(scmType, serverURL, string(apiToken)) - if err != nil { - return nil, fmt.Errorf("failed to create SCM client: %w", err) - } - - orgRepo := fmt.Sprintf("%s/%s", params[orgParam], params[repoParam]) - path := params[pathParam] - ref := params[revisionParam] - - // fetch the actual content from a file in the repo - content, _, err := scmClient.Contents.Find(ctx, orgRepo, path, ref) - if err != nil { - return nil, fmt.Errorf("couldn't fetch resource content: %w", err) - } - if content == nil || len(content.Data) == 0 { - return nil, fmt.Errorf("no content for resource in %s %s", orgRepo, path) - } - - // find the actual git commit sha by the ref - commit, _, err := scmClient.Git.FindCommit(ctx, orgRepo, ref) - if err != nil || commit == nil { - return nil, fmt.Errorf("couldn't fetch the commit sha for the ref %s in the repo: %w", ref, err) - } - - // fetch the repository URL - repo, _, err := scmClient.Repositories.Find(ctx, orgRepo) - if err != nil { - return nil, fmt.Errorf("couldn't fetch repository: %w", err) - } - - return &resolvedGitResource{ - Content: content.Data, - Revision: commit.Sha, - Org: params[orgParam], - Repo: params[repoParam], - Path: content.Path, - URL: repo.Clone, - }, nil -} - -func (r *Resolver) resolveAnonymousGit(ctx context.Context, params map[string]string) (framework.ResolvedResource, error) { +func ResolveAnonymousGit(ctx context.Context, params map[string]string) (framework.ResolvedResource, error) { conf := framework.GetResolverConfigFromContext(ctx) - repo := params[urlParam] + repo := params[UrlParam] if repo == "" { - if urlString, ok := conf[defaultURLKey]; ok { + if urlString, ok := conf[DefaultURLKey]; ok { repo = urlString } else { return nil, errors.New("default Git Repo Url was not set during installation of the git resolver") } } - revision := params[revisionParam] + revision := params[RevisionParam] if revision == "" { - if revisionString, ok := conf[defaultRevisionKey]; ok { + if revisionString, ok := conf[DefaultRevisionKey]; ok { revision = revisionString } else { return nil, errors.New("default Git Revision was not set during installation of the git resolver") @@ -271,7 +212,7 @@ func (r *Resolver) resolveAnonymousGit(ctx context.Context, params map[string]st return nil, fmt.Errorf("checkout error: %w", err) } - path := params[pathParam] + path := params[PathParam] f, err := filesystem.Open(path) if err != nil { @@ -287,8 +228,8 @@ func (r *Resolver) resolveAnonymousGit(ctx context.Context, params map[string]st return &resolvedGitResource{ Revision: h.String(), Content: buf.Bytes(), - URL: params[urlParam], - Path: params[pathParam], + URL: params[UrlParam], + Path: params[PathParam], }, nil } @@ -306,7 +247,7 @@ var _ framework.TimedResolution = &Resolver{} // fetch-timeout field in the git-resolver-config configmap. func (r *Resolver) GetResolutionTimeout(ctx context.Context, defaultTimeout time.Duration) time.Duration { conf := framework.GetResolverConfigFromContext(ctx) - if timeoutString, ok := conf[defaultTimeoutKey]; ok { + if timeoutString, ok := conf[DefaultTimeoutKey]; ok { timeout, err := time.ParseDuration(timeoutString) if err == nil { return timeout @@ -315,9 +256,66 @@ func (r *Resolver) GetResolutionTimeout(ctx context.Context, defaultTimeout time return defaultTimeout } -func (r *Resolver) isDisabled(ctx context.Context) bool { - cfg := resolverconfig.FromContextOrDefaults(ctx) - return !cfg.FeatureFlags.EnableGitResolver +func PopulateDefaultParams(ctx context.Context, params []pipelinev1.Param) (map[string]string, error) { + conf := framework.GetResolverConfigFromContext(ctx) + + paramsMap := make(map[string]string) + for _, p := range params { + paramsMap[p.Name] = p.Value.StringVal + } + + var missingParams []string + + if _, ok := paramsMap[RevisionParam]; !ok { + if defaultRevision, ok := conf[DefaultRevisionKey]; ok { + paramsMap[RevisionParam] = defaultRevision + } else { + missingParams = append(missingParams, RevisionParam) + } + } + if _, ok := paramsMap[PathParam]; !ok { + missingParams = append(missingParams, PathParam) + } + + if paramsMap[UrlParam] != "" && paramsMap[RepoParam] != "" { + return nil, fmt.Errorf("cannot specify both '%s' and '%s'", UrlParam, RepoParam) + } + + if paramsMap[UrlParam] == "" && paramsMap[RepoParam] == "" { + if urlString, ok := conf[DefaultURLKey]; ok { + paramsMap[UrlParam] = urlString + } else { + return nil, fmt.Errorf("must specify one of '%s' or '%s'", UrlParam, RepoParam) + } + } + + if paramsMap[RepoParam] != "" { + if _, ok := paramsMap[OrgParam]; !ok { + if defaultOrg, ok := conf[DefaultOrgKey]; ok { + paramsMap[OrgParam] = defaultOrg + } else { + return nil, fmt.Errorf("'%s' is required when '%s' is specified", OrgParam, RepoParam) + } + } + } + if len(missingParams) > 0 { + return nil, fmt.Errorf("missing required git resolver params: %s", strings.Join(missingParams, ", ")) + } + + // validate the url params if we are not using the SCM API + if paramsMap[RepoParam] == "" && paramsMap[OrgParam] == "" && !validateRepoURL(paramsMap[UrlParam]) { + return nil, fmt.Errorf("invalid git repository url: %s", paramsMap[UrlParam]) + } + + // TODO(sbwsg): validate pathInRepo is valid relative pathInRepo + return paramsMap, nil +} + +// supports the SPDX format which is recommended by in-toto +// ref: https://spdx.dev/spdx-specification-21-web-version/#h.49x2ik5 +// ref: https://github.com/in-toto/attestation/blob/main/spec/field_types.md +func spdxGit(url string) string { + return "git+" + url } // resolvedGitResource implements framework.ResolvedResource and returns @@ -342,10 +340,10 @@ func (r *resolvedGitResource) Data() []byte { // from git. func (r *resolvedGitResource) Annotations() map[string]string { m := map[string]string{ - AnnotationKeyRevision: r.Revision, - AnnotationKeyPath: r.Path, - AnnotationKeyURL: r.URL, - resolutioncommon.AnnotationKeyContentType: yamlContentType, + AnnotationKeyRevision: r.Revision, + AnnotationKeyPath: r.Path, + AnnotationKeyURL: r.URL, + common.AnnotationKeyContentType: yamlContentType, } if r.Org != "" { @@ -376,34 +374,69 @@ type secretCacheKey struct { key string } -func (r *Resolver) getSCMTypeAndServerURL(ctx context.Context, params map[string]string) (string, string, error) { - conf := framework.GetResolverConfigFromContext(ctx) - - var scmType, serverURL string - if key, ok := params[scmTypeParam]; ok { - scmType = key +func ResolveAPIGit(ctx context.Context, params map[string]string, kubeclient kubernetes.Interface, logger *zap.SugaredLogger, cache *cache.LRUExpireCache, ttl time.Duration, clientFunc func(string, string, string, ...factory.ClientOptionFunc) (*scm.Client, error)) (framework.ResolvedResource, error) { + // If we got here, the "repo" param was specified, so use the API approach + scmType, serverURL, err := getSCMTypeAndServerURL(ctx, params) + if err != nil { + return nil, err } - if scmType == "" { - if key, ok := conf[SCMTypeKey]; ok && scmType == "" { - scmType = key - } else { - return "", "", fmt.Errorf("missing or empty %s value in configmap", SCMTypeKey) + secretRef := &secretCacheKey{ + name: params[TokenParam], + key: params[TokenKeyParam], + } + if secretRef.name != "" { + if secretRef.key == "" { + secretRef.key = DefaultTokenKeyParam } + secretRef.ns = common.RequestNamespace(ctx) + } else { + secretRef = nil } - if key, ok := params[serverURLParam]; ok { - serverURL = key + apiToken, err := getAPIToken(ctx, secretRef, kubeclient, logger, cache, ttl) + if err != nil { + return nil, err } - if serverURL == "" { - if key, ok := conf[ServerURLKey]; ok && serverURL == "" { - serverURL = key - } else { - return "", "", fmt.Errorf("missing or empty %s value in configmap", ServerURLKey) - } + scmClient, err := clientFunc(scmType, serverURL, string(apiToken)) + if err != nil { + return nil, fmt.Errorf("failed to create SCM client: %w", err) } - return scmType, serverURL, nil + + orgRepo := fmt.Sprintf("%s/%s", params[OrgParam], params[RepoParam]) + path := params[PathParam] + ref := params[RevisionParam] + + // fetch the actual content from a file in the repo + content, _, err := scmClient.Contents.Find(ctx, orgRepo, path, ref) + if err != nil { + return nil, fmt.Errorf("couldn't fetch resource content: %w", err) + } + if content == nil || len(content.Data) == 0 { + return nil, fmt.Errorf("no content for resource in %s %s", orgRepo, path) + } + + // find the actual git commit sha by the ref + commit, _, err := scmClient.Git.FindCommit(ctx, orgRepo, ref) + if err != nil || commit == nil { + return nil, fmt.Errorf("couldn't fetch the commit sha for the ref %s in the repo: %w", ref, err) + } + + // fetch the repository URL + repo, _, err := scmClient.Repositories.Find(ctx, orgRepo) + if err != nil { + return nil, fmt.Errorf("couldn't fetch repository: %w", err) + } + + return &resolvedGitResource{ + Content: content.Data, + Revision: commit.Sha, + Org: params[OrgParam], + Repo: params[RepoParam], + Path: content.Path, + URL: repo.Clone, + }, nil } -func (r *Resolver) getAPIToken(ctx context.Context, apiSecret *secretCacheKey) ([]byte, error) { +func getAPIToken(ctx context.Context, apiSecret *secretCacheKey, kubeclient kubernetes.Interface, logger *zap.SugaredLogger, cache *cache.LRUExpireCache, ttl time.Duration) ([]byte, error) { conf := framework.GetResolverConfigFromContext(ctx) ok := false @@ -417,15 +450,15 @@ func (r *Resolver) getAPIToken(ctx context.Context, apiSecret *secretCacheKey) ( if apiSecret.name == "" { if apiSecret.name, ok = conf[APISecretNameKey]; !ok || apiSecret.name == "" { - err := fmt.Errorf("cannot get API token, required when specifying '%s' param, '%s' not specified in config", repoParam, APISecretNameKey) - r.logger.Info(err) + err := fmt.Errorf("cannot get API token, required when specifying '%s' param, '%s' not specified in config", RepoParam, APISecretNameKey) + logger.Info(err) return nil, err } } if apiSecret.key == "" { if apiSecret.key, ok = conf[APISecretKeyKey]; !ok || apiSecret.key == "" { - err := fmt.Errorf("cannot get API token, required when specifying '%s' param, '%s' not specified in config", repoParam, APISecretKeyKey) - r.logger.Info(err) + err := fmt.Errorf("cannot get API token, required when specifying '%s' param, '%s' not specified in config", RepoParam, APISecretKeyKey) + logger.Info(err) return nil, err } } @@ -436,94 +469,64 @@ func (r *Resolver) getAPIToken(ctx context.Context, apiSecret *secretCacheKey) ( } if cacheSecret { - val, ok := r.cache.Get(apiSecret) + val, ok := cache.Get(apiSecret) if ok { return val.([]byte), nil } } - secret, err := r.kubeClient.CoreV1().Secrets(apiSecret.ns).Get(ctx, apiSecret.name, metav1.GetOptions{}) + secret, err := kubeclient.CoreV1().Secrets(apiSecret.ns).Get(ctx, apiSecret.name, metav1.GetOptions{}) if err != nil { if apierrors.IsNotFound(err) { notFoundErr := fmt.Errorf("cannot get API token, secret %s not found in namespace %s", apiSecret.name, apiSecret.ns) - r.logger.Info(notFoundErr) + logger.Info(notFoundErr) return nil, notFoundErr } wrappedErr := fmt.Errorf("error reading API token from secret %s in namespace %s: %w", apiSecret.name, apiSecret.ns, err) - r.logger.Info(wrappedErr) + logger.Info(wrappedErr) return nil, wrappedErr } secretVal, ok := secret.Data[apiSecret.key] if !ok { err := fmt.Errorf("cannot get API token, key %s not found in secret %s in namespace %s", apiSecret.key, apiSecret.name, apiSecret.ns) - r.logger.Info(err) + logger.Info(err) return nil, err } if cacheSecret { - r.cache.Add(apiSecret, secretVal, r.ttl) + cache.Add(apiSecret, secretVal, ttl) } return secretVal, nil } -func populateDefaultParams(ctx context.Context, params []pipelinev1.Param) (map[string]string, error) { +func getSCMTypeAndServerURL(ctx context.Context, params map[string]string) (string, string, error) { conf := framework.GetResolverConfigFromContext(ctx) - paramsMap := make(map[string]string) - for _, p := range params { - paramsMap[p.Name] = p.Value.StringVal + var scmType, serverURL string + if key, ok := params[ScmTypeParam]; ok { + scmType = key } - - var missingParams []string - - if _, ok := paramsMap[revisionParam]; !ok { - if defaultRevision, ok := conf[defaultRevisionKey]; ok { - paramsMap[revisionParam] = defaultRevision + if scmType == "" { + if key, ok := conf[SCMTypeKey]; ok && scmType == "" { + scmType = key } else { - missingParams = append(missingParams, revisionParam) + return "", "", fmt.Errorf("missing or empty %s value in configmap", SCMTypeKey) } } - if _, ok := paramsMap[pathParam]; !ok { - missingParams = append(missingParams, pathParam) - } - - if paramsMap[urlParam] != "" && paramsMap[repoParam] != "" { - return nil, fmt.Errorf("cannot specify both '%s' and '%s'", urlParam, repoParam) + if key, ok := params[ServerURLParam]; ok { + serverURL = key } - - if paramsMap[urlParam] == "" && paramsMap[repoParam] == "" { - if urlString, ok := conf[defaultURLKey]; ok { - paramsMap[urlParam] = urlString + if serverURL == "" { + if key, ok := conf[ServerURLKey]; ok && serverURL == "" { + serverURL = key } else { - return nil, fmt.Errorf("must specify one of '%s' or '%s'", urlParam, repoParam) - } - } - - if paramsMap[repoParam] != "" { - if _, ok := paramsMap[orgParam]; !ok { - if defaultOrg, ok := conf[defaultOrgKey]; ok { - paramsMap[orgParam] = defaultOrg - } else { - return nil, fmt.Errorf("'%s' is required when '%s' is specified", orgParam, repoParam) - } + return "", "", fmt.Errorf("missing or empty %s value in configmap", ServerURLKey) } } - if len(missingParams) > 0 { - return nil, fmt.Errorf("missing required git resolver params: %s", strings.Join(missingParams, ", ")) - } - - // validate the url params if we are not using the SCM API - if paramsMap[repoParam] == "" && paramsMap[orgParam] == "" && !validateRepoURL(paramsMap[urlParam]) { - return nil, fmt.Errorf("invalid git repository url: %s", paramsMap[urlParam]) - } - - // TODO(sbwsg): validate pathInRepo is valid relative pathInRepo - return paramsMap, nil + return scmType, serverURL, nil } -// supports the SPDX format which is recommended by in-toto -// ref: https://spdx.dev/spdx-specification-21-web-version/#h.49x2ik5 -// ref: https://github.com/in-toto/attestation/blob/main/spec/field_types.md -func spdxGit(url string) string { - return "git+" + url +func IsDisabled(ctx context.Context) bool { + cfg := resolverconfig.FromContextOrDefaults(ctx) + return !cfg.FeatureFlags.EnableGitResolver } diff --git a/pkg/resolution/resolver/git/resolver_test.go b/pkg/resolution/resolver/git/resolver_test.go index a9f4c0490d9..7185abfe6aa 100644 --- a/pkg/resolution/resolver/git/resolver_test.go +++ b/pkg/resolution/resolver/git/resolver_test.go @@ -36,11 +36,11 @@ import ( resolverconfig "github.com/tektoncd/pipeline/pkg/apis/config/resolver" pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/internal/resolution" ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" - resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + common "github.com/tektoncd/pipeline/pkg/resolution/common" "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" frtesting "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework/testing" - "github.com/tektoncd/pipeline/pkg/resolution/resolver/internal" "github.com/tektoncd/pipeline/test" "github.com/tektoncd/pipeline/test/diff" corev1 "k8s.io/api/core/v1" @@ -52,7 +52,7 @@ import ( func TestGetSelector(t *testing.T) { resolver := Resolver{} sel := resolver.GetSelector(context.Background()) - if typ, has := sel[resolutioncommon.LabelKeyResolverType]; !has { + if typ, has := sel[common.LabelKeyResolverType]; !has { t.Fatalf("unexpected selector: %v", sel) } else if typ != labelValueGitResolverType { t.Fatalf("unexpected type: %q", typ) @@ -68,57 +68,57 @@ func TestValidateParams(t *testing.T) { { name: "params with revision", params: map[string]string{ - urlParam: "http://foo/bar/hello/moto", - pathParam: "bar", - revisionParam: "baz", + UrlParam: "http://foo/bar/hello/moto", + PathParam: "bar", + RevisionParam: "baz", }, }, { name: "https url", params: map[string]string{ - urlParam: "https://foo/bar/hello/moto", - pathParam: "bar", - revisionParam: "baz", + UrlParam: "https://foo/bar/hello/moto", + PathParam: "bar", + RevisionParam: "baz", }, }, { name: "https url with username password", params: map[string]string{ - urlParam: "https://user:pass@foo/bar/hello/moto", - pathParam: "bar", - revisionParam: "baz", + UrlParam: "https://user:pass@foo/bar/hello/moto", + PathParam: "bar", + RevisionParam: "baz", }, }, { name: "git server url", params: map[string]string{ - urlParam: "git://repo/hello/moto", - pathParam: "bar", - revisionParam: "baz", + UrlParam: "git://repo/hello/moto", + PathParam: "bar", + RevisionParam: "baz", }, }, { name: "git url from a local repository", params: map[string]string{ - urlParam: "/tmp/repo", - pathParam: "bar", - revisionParam: "baz", + UrlParam: "/tmp/repo", + PathParam: "bar", + RevisionParam: "baz", }, }, { name: "git url from a git ssh repository", params: map[string]string{ - urlParam: "git@host.com:foo/bar", - pathParam: "bar", - revisionParam: "baz", + UrlParam: "git@host.com:foo/bar", + PathParam: "bar", + RevisionParam: "baz", }, }, { name: "bad url", params: map[string]string{ - urlParam: "foo://bar", - pathParam: "path", - revisionParam: "revision", + UrlParam: "foo://bar", + PathParam: "path", + RevisionParam: "revision", }, wantErr: "invalid git repository url: foo://bar", }, @@ -147,8 +147,8 @@ func TestValidateParamsNotEnabled(t *testing.T) { var err error someParams := map[string]string{ - pathParam: "bar", - revisionParam: "baz", + PathParam: "bar", + RevisionParam: "baz", } err = resolver.ValidateParams(resolverDisabledContext(), toParams(someParams)) if err == nil { @@ -168,32 +168,32 @@ func TestValidateParams_Failure(t *testing.T) { { name: "missing multiple", params: map[string]string{ - orgParam: "abcd1234", - repoParam: "foo", + OrgParam: "abcd1234", + RepoParam: "foo", }, - expectedErr: fmt.Sprintf("missing required git resolver params: %s, %s", revisionParam, pathParam), + expectedErr: fmt.Sprintf("missing required git resolver params: %s, %s", RevisionParam, PathParam), }, { name: "no repo or url", params: map[string]string{ - revisionParam: "abcd1234", - pathParam: "/foo/bar", + RevisionParam: "abcd1234", + PathParam: "/foo/bar", }, expectedErr: "must specify one of 'url' or 'repo'", }, { name: "both repo and url", params: map[string]string{ - revisionParam: "abcd1234", - pathParam: "/foo/bar", - urlParam: "http://foo", - repoParam: "foo", + RevisionParam: "abcd1234", + PathParam: "/foo/bar", + UrlParam: "http://foo", + RepoParam: "foo", }, expectedErr: "cannot specify both 'url' and 'repo'", }, { name: "no org with repo", params: map[string]string{ - revisionParam: "abcd1234", - pathParam: "/foo/bar", - repoParam: "foo", + RevisionParam: "abcd1234", + PathParam: "/foo/bar", + RepoParam: "foo", }, expectedErr: "'org' is required when 'repo' is specified", }, @@ -227,7 +227,7 @@ func TestGetResolutionTimeoutCustom(t *testing.T) { defaultTimeout := 30 * time.Minute configTimeout := 5 * time.Second config := map[string]string{ - defaultTimeoutKey: configTimeout.String(), + DefaultTimeoutKey: configTimeout.String(), } ctx := framework.InjectResolverConfigToContext(context.Background(), config) timeout := resolver.GetResolutionTimeout(ctx, defaultTimeout) @@ -242,8 +242,8 @@ func TestResolveNotEnabled(t *testing.T) { var err error someParams := map[string]string{ - pathParam: "bar", - revisionParam: "baz", + PathParam: "bar", + RevisionParam: "baz", } _, err = resolver.Resolve(resolverDisabledContext(), toParams(someParams)) if err == nil { @@ -348,7 +348,7 @@ func TestResolve(t *testing.T) { url: anonFakeRepoURL, }, expectedCommitSHA: commitSHAsInAnonRepo[2], - expectedStatus: internal.CreateResolutionRequestStatusWithData([]byte("released content in main branch and in tag v1")), + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte("released content in main branch and in tag v1")), }, { name: "clone: revision is tag name", args: ¶ms{ @@ -357,7 +357,7 @@ func TestResolve(t *testing.T) { url: anonFakeRepoURL, }, expectedCommitSHA: commitSHAsInAnonRepo[2], - expectedStatus: internal.CreateResolutionRequestStatusWithData([]byte("released content in main branch and in tag v1")), + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte("released content in main branch and in tag v1")), }, { name: "clone: revision is the full tag name i.e. refs/tags/v1", args: ¶ms{ @@ -366,7 +366,7 @@ func TestResolve(t *testing.T) { url: anonFakeRepoURL, }, expectedCommitSHA: commitSHAsInAnonRepo[2], - expectedStatus: internal.CreateResolutionRequestStatusWithData([]byte("released content in main branch and in tag v1")), + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte("released content in main branch and in tag v1")), }, { name: "clone: revision is a branch name", args: ¶ms{ @@ -375,7 +375,7 @@ func TestResolve(t *testing.T) { url: anonFakeRepoURL, }, expectedCommitSHA: commitSHAsInAnonRepo[1], - expectedStatus: internal.CreateResolutionRequestStatusWithData([]byte("new content in test branch")), + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte("new content in test branch")), }, { name: "clone: revision is a specific commit sha", args: ¶ms{ @@ -384,7 +384,7 @@ func TestResolve(t *testing.T) { url: anonFakeRepoURL, }, expectedCommitSHA: commitSHAsInAnonRepo[0], - expectedStatus: internal.CreateResolutionRequestStatusWithData([]byte("old content in test branch")), + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte("old content in test branch")), }, { name: "clone: file does not exist", args: ¶ms{ @@ -417,7 +417,7 @@ func TestResolve(t *testing.T) { }, apiToken: "some-token", expectedCommitSHA: commitSHAsInSCMRepo[0], - expectedStatus: internal.CreateResolutionRequestStatusWithData(mainTaskYAML), + expectedStatus: resolution.CreateResolutionRequestStatusWithData(mainTaskYAML), }, { name: "api: successful task", args: ¶ms{ @@ -435,7 +435,7 @@ func TestResolve(t *testing.T) { }, apiToken: "some-token", expectedCommitSHA: commitSHAsInSCMRepo[0], - expectedStatus: internal.CreateResolutionRequestStatusWithData(mainTaskYAML), + expectedStatus: resolution.CreateResolutionRequestStatusWithData(mainTaskYAML), }, { name: "api: successful pipeline", args: ¶ms{ @@ -453,7 +453,7 @@ func TestResolve(t *testing.T) { }, apiToken: "some-token", expectedCommitSHA: commitSHAsInSCMRepo[0], - expectedStatus: internal.CreateResolutionRequestStatusWithData(mainPipelineYAML), + expectedStatus: resolution.CreateResolutionRequestStatusWithData(mainPipelineYAML), }, { name: "api: successful pipeline with default revision", args: ¶ms{ @@ -467,11 +467,11 @@ func TestResolve(t *testing.T) { APISecretNameKey: "token-secret", APISecretKeyKey: "token", APISecretNamespaceKey: system.Namespace(), - defaultRevisionKey: "other", + DefaultRevisionKey: "other", }, apiToken: "some-token", expectedCommitSHA: commitSHAsInSCMRepo[1], - expectedStatus: internal.CreateResolutionRequestStatusWithData(otherPipelineYAML), + expectedStatus: resolution.CreateResolutionRequestStatusWithData(otherPipelineYAML), }, { name: "api: successful override scm type and server URL from user params", @@ -492,7 +492,7 @@ func TestResolve(t *testing.T) { }, apiToken: "some-token", expectedCommitSHA: commitSHAsInSCMRepo[0], - expectedStatus: internal.CreateResolutionRequestStatusWithData(mainTaskYAML), + expectedStatus: resolution.CreateResolutionRequestStatusWithData(mainTaskYAML), }, { name: "api: file does not exist", args: ¶ms{ @@ -509,7 +509,7 @@ func TestResolve(t *testing.T) { APISecretNamespaceKey: system.Namespace(), }, apiToken: "some-token", - expectedStatus: internal.CreateResolutionRequestFailureStatus(), + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), expectedErr: createError("couldn't fetch resource content: file testdata/test-org/test-repo/refs/main/pipelines/other-pipeline.yaml does not exist: stat testdata/test-org/test-repo/refs/main/pipelines/other-pipeline.yaml: no such file or directory"), }, { name: "api: token not found", @@ -526,7 +526,7 @@ func TestResolve(t *testing.T) { APISecretKeyKey: "token", APISecretNamespaceKey: system.Namespace(), }, - expectedStatus: internal.CreateResolutionRequestFailureStatus(), + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), expectedErr: createError("cannot get API token, secret token-secret not found in namespace " + system.Namespace()), }, { name: "api: token secret name not specified", @@ -543,7 +543,7 @@ func TestResolve(t *testing.T) { APISecretNamespaceKey: system.Namespace(), }, apiToken: "some-token", - expectedStatus: internal.CreateResolutionRequestFailureStatus(), + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), expectedErr: createError("cannot get API token, required when specifying 'repo' param, 'api-token-secret-name' not specified in config"), }, { name: "api: token secret key not specified", @@ -560,7 +560,7 @@ func TestResolve(t *testing.T) { APISecretNamespaceKey: system.Namespace(), }, apiToken: "some-token", - expectedStatus: internal.CreateResolutionRequestFailureStatus(), + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), expectedErr: createError("cannot get API token, required when specifying 'repo' param, 'api-token-secret-key' not specified in config"), }, { name: "api: SCM type not specified", @@ -576,7 +576,7 @@ func TestResolve(t *testing.T) { APISecretNamespaceKey: system.Namespace(), }, apiToken: "some-token", - expectedStatus: internal.CreateResolutionRequestFailureStatus(), + expectedStatus: resolution.CreateResolutionRequestFailureStatus(), expectedErr: createError("missing or empty scm-type value in configmap"), }} @@ -588,9 +588,9 @@ func TestResolve(t *testing.T) { if cfg == nil { cfg = make(map[string]string) } - cfg[defaultTimeoutKey] = "1m" - if cfg[defaultRevisionKey] == "" { - cfg[defaultRevisionKey] = plumbing.Master.Short() + cfg[DefaultTimeoutKey] = "1m" + if cfg[DefaultRevisionKey] == "" { + cfg[DefaultRevisionKey] = plumbing.Master.Short() } request := createRequest(tc.args) @@ -623,7 +623,7 @@ func TestResolve(t *testing.T) { if expectedStatus.Annotations == nil { expectedStatus.Annotations = make(map[string]string) } - expectedStatus.Annotations[resolutioncommon.AnnotationKeyContentType] = "application/x-yaml" + expectedStatus.Annotations[common.AnnotationKeyContentType] = "application/x-yaml" expectedStatus.Annotations[AnnotationKeyRevision] = tc.expectedCommitSHA expectedStatus.Annotations[AnnotationKeyPath] = tc.args.pathInRepo @@ -819,12 +819,12 @@ func createRequest(args *params) *v1beta1.ResolutionRequest { Namespace: "foo", CreationTimestamp: metav1.Time{Time: time.Now()}, Labels: map[string]string{ - resolutioncommon.LabelKeyResolverType: labelValueGitResolverType, + common.LabelKeyResolverType: labelValueGitResolverType, }, }, Spec: v1beta1.ResolutionRequestSpec{ Params: []pipelinev1.Param{{ - Name: pathParam, + Name: PathParam, Value: *pipelinev1.NewStructuredValues(args.pathInRepo), }}, }, @@ -832,45 +832,45 @@ func createRequest(args *params) *v1beta1.ResolutionRequest { if args.revision != "" { rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ - Name: revisionParam, + Name: RevisionParam, Value: *pipelinev1.NewStructuredValues(args.revision), }) } if args.serverURL != "" { rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ - Name: serverURLParam, + Name: ServerURLParam, Value: *pipelinev1.NewStructuredValues(args.serverURL), }) } if args.scmType != "" { rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ - Name: scmTypeParam, + Name: ScmTypeParam, Value: *pipelinev1.NewStructuredValues(args.scmType), }) } if args.url != "" { rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ - Name: urlParam, + Name: UrlParam, Value: *pipelinev1.NewStructuredValues(args.url), }) } else { rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ - Name: repoParam, + Name: RepoParam, Value: *pipelinev1.NewStructuredValues(args.repo), }) rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ - Name: orgParam, + Name: OrgParam, Value: *pipelinev1.NewStructuredValues(args.org), }) if args.token != "" { rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ - Name: tokenParam, + Name: TokenParam, Value: *pipelinev1.NewStructuredValues(args.token), }) rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ - Name: tokenKeyParam, + Name: TokenKeyParam, Value: *pipelinev1.NewStructuredValues(args.tokenKey), }) } @@ -884,7 +884,7 @@ func resolverDisabledContext() context.Context { } func createError(msg string) error { - return &resolutioncommon.GetResourceError{ + return &common.GetResourceError{ ResolverName: gitResolverName, Key: "foo/rr", Original: errors.New(msg), diff --git a/pkg/resolution/resolver/http/config.go b/pkg/resolution/resolver/http/config.go index 0685fdb07ba..c8ffd8ed545 100644 --- a/pkg/resolution/resolver/http/config.go +++ b/pkg/resolution/resolver/http/config.go @@ -17,7 +17,7 @@ limitations under the License. package http const ( - // timeoutKey is the configuration field name for controlling + // TimeoutKey is the configuration field name for controlling // the maximum duration of a resolution request for a file from http. - timeoutKey = "fetch-timeout" + TimeoutKey = "fetch-timeout" ) diff --git a/pkg/resolution/resolver/http/params.go b/pkg/resolution/resolver/http/params.go index b2e8c9a9c6c..d58008b5942 100644 --- a/pkg/resolution/resolver/http/params.go +++ b/pkg/resolution/resolver/http/params.go @@ -14,15 +14,15 @@ limitations under the License. package http const ( - // urlParam is the URL to fetch the task from - urlParam string = "url" + // UrlParam is the URL to fetch the task from + UrlParam string = "url" - // httpBasicAuthUsername is the user name to use for basic auth - httpBasicAuthUsername string = "http-username" + // HttpBasicAuthUsername is the user name to use for basic auth + HttpBasicAuthUsername string = "http-username" - // httpBasicAuthSecret is the reference to a secret in the PipelineRun or TaskRun namespace to use for basic auth - httpBasicAuthSecret string = "http-password-secret" + // HttpBasicAuthSecret is the reference to a secret in the PipelineRun or TaskRun namespace to use for basic auth + HttpBasicAuthSecret string = "http-password-secret" - // httpBasicAuthSecretKey is the key in the httpBasicAuthSecret secret to use for basic auth - httpBasicAuthSecretKey string = "http-password-secret-key" + // HttpBasicAuthSecretKey is the key in the httpBasicAuthSecret secret to use for basic auth + HttpBasicAuthSecretKey string = "http-password-secret-key" ) diff --git a/pkg/resolution/resolver/http/resolver.go b/pkg/resolution/resolver/http/resolver.go index 49d75bd2dd1..1b9c9e7c921 100644 --- a/pkg/resolution/resolver/http/resolver.go +++ b/pkg/resolution/resolver/http/resolver.go @@ -28,7 +28,7 @@ import ( resolverconfig "github.com/tektoncd/pipeline/pkg/apis/config/resolver" pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" - "github.com/tektoncd/pipeline/pkg/resolution/common" + common "github.com/tektoncd/pipeline/pkg/resolution/common" "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" "go.uber.org/zap" apierrors "k8s.io/apimachinery/pkg/api/errors" @@ -89,31 +89,24 @@ 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 { - if r.isDisabled(ctx) { - return errors.New(disabledError) - } - _, err := populateDefaultParams(ctx, params) - if err != nil { - return err - } - return nil + return ValidateParams(ctx, params) } // Resolve uses the given params to resolve the requested file or resource. func (r *Resolver) Resolve(ctx context.Context, oParams []pipelinev1.Param) (framework.ResolvedResource, error) { - if r.isDisabled(ctx) { + if IsDisabled(ctx) { return nil, errors.New(disabledError) } - params, err := populateDefaultParams(ctx, oParams) + params, err := PopulateDefaultParams(ctx, oParams) if err != nil { return nil, err } - return r.fetchHttpResource(ctx, params) + return FetchHttpResource(ctx, params, r.kubeClient, r.logger) } -func (r *Resolver) isDisabled(ctx context.Context) bool { +func IsDisabled(ctx context.Context) bool { cfg := resolverconfig.FromContextOrDefaults(ctx) return !cfg.FeatureFlags.EnableHttpResolver } @@ -151,7 +144,7 @@ func (rr *resolvedHttpResource) RefSource() *pipelinev1.RefSource { } } -func populateDefaultParams(ctx context.Context, params []pipelinev1.Param) (map[string]string, error) { +func PopulateDefaultParams(ctx context.Context, params []pipelinev1.Param) (map[string]string, error) { paramsMap := make(map[string]string) for _, p := range params { paramsMap[p.Name] = p.Value.StringVal @@ -159,33 +152,33 @@ func populateDefaultParams(ctx context.Context, params []pipelinev1.Param) (map[ var missingParams []string - if _, ok := paramsMap[urlParam]; !ok { - missingParams = append(missingParams, urlParam) + if _, ok := paramsMap[UrlParam]; !ok { + missingParams = append(missingParams, UrlParam) } else { - u, err := url.ParseRequestURI(paramsMap[urlParam]) + u, err := url.ParseRequestURI(paramsMap[UrlParam]) if err != nil { - return nil, fmt.Errorf("cannot parse url %s: %w", paramsMap[urlParam], err) + return nil, fmt.Errorf("cannot parse url %s: %w", paramsMap[UrlParam], err) } if u.Scheme != "http" && u.Scheme != "https" { - return nil, fmt.Errorf("url %s is not a valid http(s) url", paramsMap[urlParam]) + return nil, fmt.Errorf("url %s is not a valid http(s) url", paramsMap[UrlParam]) } } - if username, ok := paramsMap[httpBasicAuthUsername]; ok { - if _, ok := paramsMap[httpBasicAuthSecret]; !ok { - return nil, fmt.Errorf("missing required param %s when using %s", httpBasicAuthSecret, httpBasicAuthUsername) + if username, ok := paramsMap[HttpBasicAuthUsername]; ok { + if _, ok := paramsMap[HttpBasicAuthSecret]; !ok { + return nil, fmt.Errorf("missing required param %s when using %s", HttpBasicAuthSecret, HttpBasicAuthUsername) } if username == "" { - return nil, fmt.Errorf("value %s cannot be empty", httpBasicAuthUsername) + return nil, fmt.Errorf("value %s cannot be empty", HttpBasicAuthUsername) } } - if secret, ok := paramsMap[httpBasicAuthSecret]; ok { - if _, ok := paramsMap[httpBasicAuthUsername]; !ok { - return nil, fmt.Errorf("missing required param %s when using %s", httpBasicAuthUsername, httpBasicAuthSecret) + if secret, ok := paramsMap[HttpBasicAuthSecret]; ok { + if _, ok := paramsMap[HttpBasicAuthUsername]; !ok { + return nil, fmt.Errorf("missing required param %s when using %s", HttpBasicAuthUsername, HttpBasicAuthSecret) } if secret == "" { - return nil, fmt.Errorf("value %s cannot be empty", httpBasicAuthSecret) + return nil, fmt.Errorf("value %s cannot be empty", HttpBasicAuthSecret) } } @@ -199,7 +192,7 @@ func populateDefaultParams(ctx context.Context, params []pipelinev1.Param) (map[ func makeHttpClient(ctx context.Context) (*http.Client, error) { conf := framework.GetResolverConfigFromContext(ctx) timeout, _ := time.ParseDuration(defaultHttpTimeoutValue) - if v, ok := conf[timeoutKey]; ok { + if v, ok := conf[TimeoutKey]; ok { var err error timeout, err = time.ParseDuration(v) if err != nil { @@ -211,7 +204,7 @@ func makeHttpClient(ctx context.Context) (*http.Client, error) { }, nil } -func (r *Resolver) fetchHttpResource(ctx context.Context, params map[string]string) (framework.ResolvedResource, error) { +func FetchHttpResource(ctx context.Context, params map[string]string, kubeclient kubernetes.Interface, logger *zap.SugaredLogger) (framework.ResolvedResource, error) { var targetURL string var ok bool @@ -220,8 +213,8 @@ func (r *Resolver) fetchHttpResource(ctx context.Context, params map[string]stri return nil, err } - if targetURL, ok = params[urlParam]; !ok { - return nil, fmt.Errorf("missing required params: %s", urlParam) + if targetURL, ok = params[UrlParam]; !ok { + return nil, fmt.Errorf("missing required params: %s", UrlParam) } req, err := http.NewRequestWithContext(ctx, http.MethodGet, targetURL, nil) @@ -230,8 +223,8 @@ func (r *Resolver) fetchHttpResource(ctx context.Context, params map[string]stri } // NOTE(chmouel): We already made sure that username and secret was specified by the user - if secret, ok := params[httpBasicAuthSecret]; ok && secret != "" { - if encodedSecret, err := r.getBasicAuthSecret(ctx, params); err != nil { + if secret, ok := params[HttpBasicAuthSecret]; ok && secret != "" { + if encodedSecret, err := getBasicAuthSecret(ctx, params, kubeclient, logger); err != nil { return nil, err } else { req.Header.Set("Authorization", encodedSecret) @@ -259,33 +252,44 @@ func (r *Resolver) fetchHttpResource(ctx context.Context, params map[string]stri }, nil } -func (r *Resolver) getBasicAuthSecret(ctx context.Context, params map[string]string) (string, error) { - secretName := params[httpBasicAuthSecret] - userName := params[httpBasicAuthUsername] +func getBasicAuthSecret(ctx context.Context, params map[string]string, kubeclient kubernetes.Interface, logger *zap.SugaredLogger) (string, error) { + secretName := params[HttpBasicAuthSecret] + userName := params[HttpBasicAuthUsername] tokenSecretKey := defaultBasicAuthSecretKey - if v, ok := params[httpBasicAuthSecretKey]; ok { + if v, ok := params[HttpBasicAuthSecretKey]; ok { if v != "" { tokenSecretKey = v } } secretNS := common.RequestNamespace(ctx) - secret, err := r.kubeClient.CoreV1().Secrets(secretNS).Get(ctx, secretName, metav1.GetOptions{}) + secret, err := kubeclient.CoreV1().Secrets(secretNS).Get(ctx, secretName, metav1.GetOptions{}) if err != nil { if apierrors.IsNotFound(err) { notFoundErr := fmt.Errorf("cannot get API token, secret %s not found in namespace %s", secretName, secretNS) - r.logger.Info(notFoundErr) + logger.Info(notFoundErr) return "", notFoundErr } wrappedErr := fmt.Errorf("error reading API token from secret %s in namespace %s: %w", secretName, secretNS, err) - r.logger.Info(wrappedErr) + logger.Info(wrappedErr) return "", wrappedErr } secretVal, ok := secret.Data[tokenSecretKey] if !ok { err := fmt.Errorf("cannot get API token, key %s not found in secret %s in namespace %s", tokenSecretKey, secretName, secretNS) - r.logger.Info(err) + logger.Info(err) return "", err } return "Basic " + base64.StdEncoding.EncodeToString( []byte(fmt.Sprintf("%s:%s", userName, secretVal))), nil } + +func ValidateParams(ctx context.Context, params []pipelinev1.Param) error { + if IsDisabled(ctx) { + return errors.New(disabledError) + } + _, err := PopulateDefaultParams(ctx, params) + if err != nil { + return err + } + return nil +} diff --git a/pkg/resolution/resolver/http/resolver_test.go b/pkg/resolution/resolver/http/resolver_test.go index 630b3882d6e..dddfab29dbf 100644 --- a/pkg/resolution/resolver/http/resolver_test.go +++ b/pkg/resolution/resolver/http/resolver_test.go @@ -33,11 +33,11 @@ import ( resolverconfig "github.com/tektoncd/pipeline/pkg/apis/config/resolver" pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "github.com/tektoncd/pipeline/pkg/internal/resolution" ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" - resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + common "github.com/tektoncd/pipeline/pkg/resolution/common" "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" frtesting "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework/testing" - "github.com/tektoncd/pipeline/pkg/resolution/resolver/internal" "github.com/tektoncd/pipeline/test" "github.com/tektoncd/pipeline/test/diff" corev1 "k8s.io/api/core/v1" @@ -68,7 +68,7 @@ const emptyStr = "empty" func TestGetSelector(t *testing.T) { resolver := Resolver{} sel := resolver.GetSelector(context.Background()) - if typ, has := sel[resolutioncommon.LabelKeyResolverType]; !has { + if typ, has := sel[common.LabelKeyResolverType]; !has { t.Fatalf("unexpected selector: %v", sel) } else if typ != LabelValueHttpResolverType { t.Fatalf("unexpected type: %q", typ) @@ -104,7 +104,7 @@ func TestValidateParams(t *testing.T) { resolver := Resolver{} params := map[string]string{} if tc.url != "nourl" { - params[urlParam] = tc.url + params[UrlParam] = tc.url } err := resolver.ValidateParams(contextWithConfig(defaultHttpTimeoutValue), toParams(params)) if tc.expectedErr != nil { @@ -186,7 +186,7 @@ func TestResolve(t *testing.T) { params := []pipelinev1.Param{} if tc.paramSet { params = append(params, pipelinev1.Param{ - Name: urlParam, + Name: UrlParam, Value: *pipelinev1.NewStructuredValues(svr.URL), }) } @@ -253,12 +253,12 @@ func createRequest(params *params) *v1beta1.ResolutionRequest { Namespace: "foo", CreationTimestamp: metav1.Time{Time: time.Now()}, Labels: map[string]string{ - resolutioncommon.LabelKeyResolverType: LabelValueHttpResolverType, + common.LabelKeyResolverType: LabelValueHttpResolverType, }, }, Spec: v1beta1.ResolutionRequestSpec{ Params: []pipelinev1.Param{{ - Name: urlParam, + Name: UrlParam, Value: *pipelinev1.NewStructuredValues(params.url), }}, }, @@ -269,7 +269,7 @@ func createRequest(params *params) *v1beta1.ResolutionRequest { s = "" } rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ - Name: httpBasicAuthSecret, + Name: HttpBasicAuthSecret, Value: *pipelinev1.NewStructuredValues(s), }) } @@ -280,14 +280,14 @@ func createRequest(params *params) *v1beta1.ResolutionRequest { s = "" } rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ - Name: httpBasicAuthUsername, + Name: HttpBasicAuthUsername, Value: *pipelinev1.NewStructuredValues(s), }) } if params.authSecretKey != "" { rr.Spec.Params = append(rr.Spec.Params, pipelinev1.Param{ - Name: httpBasicAuthSecretKey, + Name: HttpBasicAuthSecretKey, Value: *pipelinev1.NewStructuredValues(params.authSecretKey), }) } @@ -309,12 +309,12 @@ func TestResolverReconcileBasicAuth(t *testing.T) { { name: "good/URL Resolution", taskContent: sampleTask, - expectedStatus: internal.CreateResolutionRequestStatusWithData([]byte(sampleTask)), + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte(sampleTask)), }, { name: "good/URL Resolution with custom basic auth, and custom secret key", taskContent: sampleTask, - expectedStatus: internal.CreateResolutionRequestStatusWithData([]byte(sampleTask)), + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte(sampleTask)), params: ¶ms{ authSecret: "auth-secret", authUsername: "auth", @@ -325,7 +325,7 @@ func TestResolverReconcileBasicAuth(t *testing.T) { { name: "good/URL Resolution with custom basic auth no custom secret key", taskContent: sampleTask, - expectedStatus: internal.CreateResolutionRequestStatusWithData([]byte(sampleTask)), + expectedStatus: resolution.CreateResolutionRequestStatusWithData([]byte(sampleTask)), params: ¶ms{ authSecret: "auth-secret", authUsername: "auth", @@ -510,7 +510,7 @@ func toParams(m map[string]string) []pipelinev1.Param { func contextWithConfig(timeout string) context.Context { config := map[string]string{ - timeoutKey: timeout, + TimeoutKey: timeout, } return framework.InjectResolverConfigToContext(context.Background(), config) } diff --git a/pkg/resolution/resolver/hub/resolver.go b/pkg/resolution/resolver/hub/resolver.go index e94aa390fa5..a4f11726f99 100644 --- a/pkg/resolution/resolver/hub/resolver.go +++ b/pkg/resolution/resolver/hub/resolver.go @@ -27,7 +27,7 @@ import ( goversion "github.com/hashicorp/go-version" resolverconfig "github.com/tektoncd/pipeline/pkg/apis/config/resolver" pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" - "github.com/tektoncd/pipeline/pkg/resolution/common" + common "github.com/tektoncd/pipeline/pkg/resolution/common" "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" ) @@ -77,7 +77,11 @@ 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 { - if r.isDisabled(ctx) { + return ValidateParams(ctx, params, r.TektonHubURL) +} + +func ValidateParams(ctx context.Context, params []pipelinev1.Param, tektonHubUrl string) error { + if isDisabled(ctx) { return errors.New(disabledError) } @@ -85,7 +89,7 @@ func (r *Resolver) ValidateParams(ctx context.Context, params []pipelinev1.Param if err != nil { return fmt.Errorf("failed to populate default params: %w", err) } - if err := r.validateParams(ctx, paramsMap); err != nil { + if err := validateParams(ctx, paramsMap, tektonHubUrl); err != nil { return fmt.Errorf("failed to validate params: %w", err) } @@ -110,7 +114,11 @@ type artifactHubResponse struct { // 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) { - if r.isDisabled(ctx) { + return Resolve(ctx, params, r.TektonHubURL, r.ArtifactHubURL) +} + +func Resolve(ctx context.Context, params []pipelinev1.Param, tektonHubURL, artifactHubURL string) (framework.ResolvedResource, error) { + if isDisabled(ctx) { return nil, errors.New(disabledError) } @@ -118,12 +126,12 @@ func (r *Resolver) Resolve(ctx context.Context, params []pipelinev1.Param) (fram if err != nil { return nil, fmt.Errorf("failed to populate default params: %w", err) } - if err := r.validateParams(ctx, paramsMap); err != nil { + if err := validateParams(ctx, paramsMap, tektonHubURL); err != nil { return nil, fmt.Errorf("failed to validate params: %w", err) } if constraint, err := goversion.NewConstraint(paramsMap[ParamVersion]); err == nil { - chosen, err := r.resolveVersionConstraint(ctx, paramsMap, constraint) + chosen, err := resolveVersionConstraint(ctx, paramsMap, constraint, artifactHubURL, tektonHubURL) if err != nil { return nil, err } @@ -139,7 +147,7 @@ func (r *Resolver) Resolve(ctx context.Context, params []pipelinev1.Param) (fram // call hub API switch paramsMap[ParamType] { case ArtifactHubType: - url := fmt.Sprintf(fmt.Sprintf("%s/%s", r.ArtifactHubURL, ArtifactHubYamlEndpoint), + url := fmt.Sprintf(fmt.Sprintf("%s/%s", artifactHubURL, ArtifactHubYamlEndpoint), paramsMap[ParamKind], paramsMap[ParamCatalog], paramsMap[ParamName], paramsMap[ParamVersion]) resp := artifactHubResponse{} if err := fetchHubResource(ctx, url, &resp); err != nil { @@ -150,7 +158,7 @@ func (r *Resolver) Resolve(ctx context.Context, params []pipelinev1.Param) (fram Content: []byte(resp.Data.YAML), }, nil case TektonHubType: - url := fmt.Sprintf(fmt.Sprintf("%s/%s", r.TektonHubURL, TektonHubYamlEndpoint), + url := fmt.Sprintf(fmt.Sprintf("%s/%s", tektonHubURL, TektonHubYamlEndpoint), paramsMap[ParamCatalog], paramsMap[ParamKind], paramsMap[ParamName], paramsMap[ParamVersion]) resp := tektonHubResponse{} if err := fetchHubResource(ctx, url, &resp); err != nil { @@ -198,7 +206,7 @@ func (rr *ResolvedHubResource) RefSource() *pipelinev1.RefSource { } } -func (r *Resolver) isDisabled(ctx context.Context) bool { +func isDisabled(ctx context.Context) bool { cfg := resolverconfig.FromContextOrDefaults(ctx) return !cfg.FeatureFlags.EnableHubResolver } @@ -288,10 +296,92 @@ type tektonHubListResult struct { Data tektonHubListDataResult `json:"data"` } -func (r *Resolver) resolveVersionConstraint(ctx context.Context, paramsMap map[string]string, constraint goversion.Constraints) (*goversion.Version, error) { +// the Artifact Hub follows the semVer (i.e. ..0) +// the Tekton Hub follows the simplified semVer (i.e. .) +// for resolution request with "artifact" type, we append ".0" suffix if the input version is simplified semVer +// for resolution request with "tekton" type, we only use . part of the input if it is semVer +func resolveVersion(version, hubType string) (string, error) { + semVer := strings.Split(version, ".") + resVer := version + + if hubType == ArtifactHubType && len(semVer) == 2 { + resVer = version + ".0" + } else if hubType == TektonHubType && len(semVer) > 2 { + resVer = strings.Join(semVer[0:2], ".") + } + + return resVer, nil +} + +func populateDefaultParams(ctx context.Context, params []pipelinev1.Param) (map[string]string, error) { + conf := framework.GetResolverConfigFromContext(ctx) + paramsMap := make(map[string]string) + for _, p := range params { + paramsMap[p.Name] = p.Value.StringVal + } + + // type + if _, ok := paramsMap[ParamType]; !ok { + if typeString, ok := conf[ConfigType]; ok { + paramsMap[ParamType] = typeString + } else { + return nil, errors.New("default type was not set during installation of the hub resolver") + } + } + + // kind + if _, ok := paramsMap[ParamKind]; !ok { + if kindString, ok := conf[ConfigKind]; ok { + paramsMap[ParamKind] = kindString + } else { + return nil, errors.New("default resource kind was not set during installation of the hub resolver") + } + } + + // catalog + resCatName, err := resolveCatalogName(paramsMap, conf) + if err != nil { + return nil, err + } + paramsMap[ParamCatalog] = resCatName + + return paramsMap, nil +} + +func validateParams(ctx context.Context, paramsMap map[string]string, tektonHubURL string) error { + var missingParams []string + if _, ok := paramsMap[ParamName]; !ok { + missingParams = append(missingParams, ParamName) + } + if _, ok := paramsMap[ParamVersion]; !ok { + missingParams = append(missingParams, ParamVersion) + } + if kind, ok := paramsMap[ParamKind]; ok { + if kind != "task" && kind != "pipeline" { + return errors.New("kind param must be task or pipeline") + } + } + if hubType, ok := paramsMap[ParamType]; ok { + if hubType != ArtifactHubType && hubType != TektonHubType { + return fmt.Errorf("type param must be %s or %s", ArtifactHubType, TektonHubType) + } + + if hubType == TektonHubType && tektonHubURL == "" { + return errors.New("please configure TEKTON_HUB_API env variable to use tekton type") + } + } + + if len(missingParams) > 0 { + return fmt.Errorf("missing required hub resolver params: %s", strings.Join(missingParams, ", ")) + } + + return nil +} + +func resolveVersionConstraint(ctx context.Context, paramsMap map[string]string, constraint goversion.Constraints, artifactHubURL, tektonHubURL string) (*goversion.Version, error) { var ret *goversion.Version if paramsMap[ParamType] == ArtifactHubType { - allVersionsURL := fmt.Sprintf("%s/%s", r.ArtifactHubURL, fmt.Sprintf( + allVersionsURL := fmt.Sprintf("%s/%s", artifactHubURL, fmt.Sprintf( ArtifactHubListTasksEndpoint, paramsMap[ParamKind], paramsMap[ParamCatalog], paramsMap[ParamName])) resp := artifactHubListResult{} @@ -318,7 +408,7 @@ func (r *Resolver) resolveVersionConstraint(ctx context.Context, paramsMap map[s } } } else if paramsMap[ParamType] == TektonHubType { - allVersionsURL := fmt.Sprintf("%s/%s", r.TektonHubURL, + allVersionsURL := fmt.Sprintf("%s/%s", tektonHubURL, fmt.Sprintf(TektonHubListTasksEndpoint, paramsMap[ParamCatalog], paramsMap[ParamKind], paramsMap[ParamName])) resp := tektonHubListResult{} @@ -347,85 +437,3 @@ func (r *Resolver) resolveVersionConstraint(ctx context.Context, paramsMap map[s } return ret, nil } - -// the Artifact Hub follows the semVer (i.e. ..0) -// the Tekton Hub follows the simplified semVer (i.e. .) -// for resolution request with "artifact" type, we append ".0" suffix if the input version is simplified semVer -// for resolution request with "tekton" type, we only use . part of the input if it is semVer -func resolveVersion(version, hubType string) (string, error) { - semVer := strings.Split(version, ".") - resVer := version - - if hubType == ArtifactHubType && len(semVer) == 2 { - resVer = version + ".0" - } else if hubType == TektonHubType && len(semVer) > 2 { - resVer = strings.Join(semVer[0:2], ".") - } - - return resVer, nil -} - -func (r *Resolver) validateParams(ctx context.Context, paramsMap map[string]string) error { - var missingParams []string - if _, ok := paramsMap[ParamName]; !ok { - missingParams = append(missingParams, ParamName) - } - if _, ok := paramsMap[ParamVersion]; !ok { - missingParams = append(missingParams, ParamVersion) - } - if kind, ok := paramsMap[ParamKind]; ok { - if kind != "task" && kind != "pipeline" { - return errors.New("kind param must be task or pipeline") - } - } - if hubType, ok := paramsMap[ParamType]; ok { - if hubType != ArtifactHubType && hubType != TektonHubType { - return fmt.Errorf("type param must be %s or %s", ArtifactHubType, TektonHubType) - } - - if hubType == TektonHubType && r.TektonHubURL == "" { - return errors.New("please configure TEKTON_HUB_API env variable to use tekton type") - } - } - - if len(missingParams) > 0 { - return fmt.Errorf("missing required hub resolver params: %s", strings.Join(missingParams, ", ")) - } - - return nil -} - -func populateDefaultParams(ctx context.Context, params []pipelinev1.Param) (map[string]string, error) { - conf := framework.GetResolverConfigFromContext(ctx) - paramsMap := make(map[string]string) - for _, p := range params { - paramsMap[p.Name] = p.Value.StringVal - } - - // type - if _, ok := paramsMap[ParamType]; !ok { - if typeString, ok := conf[ConfigType]; ok { - paramsMap[ParamType] = typeString - } else { - return nil, errors.New("default type was not set during installation of the hub resolver") - } - } - - // kind - if _, ok := paramsMap[ParamKind]; !ok { - if kindString, ok := conf[ConfigKind]; ok { - paramsMap[ParamKind] = kindString - } else { - return nil, errors.New("default resource kind was not set during installation of the hub resolver") - } - } - - // catalog - resCatName, err := resolveCatalogName(paramsMap, conf) - if err != nil { - return nil, err - } - paramsMap[ParamCatalog] = resCatName - - return paramsMap, nil -} diff --git a/pkg/resolution/resolver/hub/resolver_test.go b/pkg/resolution/resolver/hub/resolver_test.go index 474838c1a7f..918d3a8d521 100644 --- a/pkg/resolution/resolver/hub/resolver_test.go +++ b/pkg/resolution/resolver/hub/resolver_test.go @@ -29,7 +29,7 @@ import ( "github.com/google/go-cmp/cmp" pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" - resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + common "github.com/tektoncd/pipeline/pkg/resolution/common" "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" frtesting "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework/testing" "github.com/tektoncd/pipeline/test/diff" @@ -38,7 +38,7 @@ import ( func TestGetSelector(t *testing.T) { resolver := Resolver{} sel := resolver.GetSelector(context.Background()) - if typ, has := sel[resolutioncommon.LabelKeyResolverType]; !has { + if typ, has := sel[common.LabelKeyResolverType]; !has { t.Fatalf("unexpected selector: %v", sel) } else if typ != LabelValueHubResolverType { t.Fatalf("unexpected type: %q", typ) diff --git a/pkg/resolution/resource/crd_resource.go b/pkg/resolution/resource/crd_resource.go index 90fd7653303..39e41692075 100644 --- a/pkg/resolution/resource/crd_resource.go +++ b/pkg/resolution/resource/crd_resource.go @@ -22,11 +22,11 @@ import ( "errors" "fmt" - 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" rrclient "github.com/tektoncd/pipeline/pkg/client/resolution/clientset/versioned" rrlisters "github.com/tektoncd/pipeline/pkg/client/resolution/listers/resolution/v1beta1" - resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + common "github.com/tektoncd/pipeline/pkg/resolution/common" apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/pkg/apis" @@ -63,7 +63,7 @@ func (r *CRDRequester) Submit(ctx context.Context, resolver ResolverName, req Re !apierrors.IsAlreadyExists(err) { return nil, err } - return nil, resolutioncommon.ErrRequestInProgress + return nil, common.ErrRequestInProgress } if rr.Status.GetCondition(apis.ConditionSucceeded).IsUnknown() { @@ -72,53 +72,59 @@ func (r *CRDRequester) Submit(ctx context.Context, resolver ResolverName, req Re // that it doesn't get deleted until the caller is done // with it. Use appendOwnerReference and then submit // update to ResolutionRequest. - return nil, resolutioncommon.ErrRequestInProgress + return nil, common.ErrRequestInProgress } if rr.Status.GetCondition(apis.ConditionSucceeded).IsTrue() { - return crdIntoResource(rr), nil + return CrdIntoResource(rr), nil } message := rr.Status.GetCondition(apis.ConditionSucceeded).GetMessage() - err := resolutioncommon.NewError(resolutioncommon.ReasonResolutionFailed, errors.New(message)) + err := common.NewError(common.ReasonResolutionFailed, errors.New(message)) return nil, err } func (r *CRDRequester) createResolutionRequest(ctx context.Context, resolver ResolverName, req Request) error { + var owner metav1.OwnerReference + if ownedReq, ok := req.(OwnedRequest); ok { + owner = ownedReq.OwnerRef() + } + rr := CreateResolutionRequest(ctx, resolver, req.Name(), req.Namespace(), req.Params(), owner) + _, err := r.clientset.ResolutionV1beta1().ResolutionRequests(rr.Namespace).Create(ctx, rr, metav1.CreateOptions{}) + return err +} + +func CreateResolutionRequest(ctx context.Context, resolver common.ResolverName, name, namespace string, params []v1.Param, ownerRef metav1.OwnerReference) *v1beta1.ResolutionRequest { rr := &v1beta1.ResolutionRequest{ TypeMeta: metav1.TypeMeta{ APIVersion: "resolution.tekton.dev/v1beta1", Kind: "ResolutionRequest", }, ObjectMeta: metav1.ObjectMeta{ - Name: req.Name(), - Namespace: req.Namespace(), + Name: name, + Namespace: namespace, Labels: map[string]string{ - resolutioncommon.LabelKeyResolverType: string(resolver), + common.LabelKeyResolverType: string(resolver), }, }, Spec: v1beta1.ResolutionRequestSpec{ - Params: req.Params(), + Params: params, }, } - appendOwnerReference(rr, req) - _, err := r.clientset.ResolutionV1beta1().ResolutionRequests(rr.Namespace).Create(ctx, rr, metav1.CreateOptions{}) - return err + appendOwnerReference(rr, ownerRef) + return rr } -func appendOwnerReference(rr *v1beta1.ResolutionRequest, req Request) { - if ownedReq, ok := req.(OwnedRequest); ok { - newOwnerRef := ownedReq.OwnerRef() - isOwner := false - for _, ref := range rr.ObjectMeta.OwnerReferences { - if ownerRefsAreEqual(ref, newOwnerRef) { - isOwner = true - } - } - if !isOwner { - rr.ObjectMeta.OwnerReferences = append(rr.ObjectMeta.OwnerReferences, newOwnerRef) +func appendOwnerReference(rr *v1beta1.ResolutionRequest, ownerRef metav1.OwnerReference) { + isOwner := false + for _, ref := range rr.ObjectMeta.OwnerReferences { + if ownerRefsAreEqual(ref, ownerRef) { + isOwner = true } } + if !isOwner { + rr.ObjectMeta.OwnerReferences = append(rr.ObjectMeta.OwnerReferences, ownerRef) + } } func ownerRefsAreEqual(a, b metav1.OwnerReference) bool { @@ -131,21 +137,21 @@ func ownerRefsAreEqual(a, b metav1.OwnerReference) bool { return a.APIVersion == b.APIVersion && a.Kind == b.Kind && a.Name == b.Name && a.UID == b.UID } -// readOnlyResolutionRequest is an opaque wrapper around ResolutionRequest +// ReadOnlyResolutionRequest is an opaque wrapper around ResolutionRequest // that provides the methods needed to read data from it using the // Resource interface without exposing the underlying API // object. -type readOnlyResolutionRequest struct { +type ReadOnlyResolutionRequest struct { req *v1beta1.ResolutionRequest } -var _ ResolvedResource = readOnlyResolutionRequest{} +var _ common.ResolvedResource = ReadOnlyResolutionRequest{} -func crdIntoResource(rr *v1beta1.ResolutionRequest) readOnlyResolutionRequest { - return readOnlyResolutionRequest{req: rr} +func CrdIntoResource(rr *v1beta1.ResolutionRequest) ReadOnlyResolutionRequest { + return ReadOnlyResolutionRequest{req: rr} } -func (r readOnlyResolutionRequest) Annotations() map[string]string { +func (r ReadOnlyResolutionRequest) Annotations() map[string]string { status := r.req.GetStatus() if status != nil && status.Annotations != nil { annotationsCopy := map[string]string{} @@ -157,7 +163,7 @@ func (r readOnlyResolutionRequest) Annotations() map[string]string { return nil } -func (r readOnlyResolutionRequest) Data() ([]byte, error) { +func (r ReadOnlyResolutionRequest) Data() ([]byte, error) { encodedData := r.req.Status.ResolutionRequestStatusFields.Data decodedBytes, err := base64.StdEncoding.Strict().DecodeString(encodedData) if err != nil { @@ -166,6 +172,6 @@ func (r readOnlyResolutionRequest) Data() ([]byte, error) { return decodedBytes, nil } -func (r readOnlyResolutionRequest) RefSource() *pipelinev1.RefSource { +func (r ReadOnlyResolutionRequest) RefSource() *v1.RefSource { return r.req.Status.RefSource } diff --git a/pkg/resolution/resource/crd_resource_test.go b/pkg/resolution/resource/crd_resource_test.go index da5a06fac38..c63a3564977 100644 --- a/pkg/resolution/resource/crd_resource_test.go +++ b/pkg/resolution/resource/crd_resource_test.go @@ -25,10 +25,11 @@ import ( "github.com/google/go-cmp/cmp" "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" - resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" + "github.com/tektoncd/pipeline/pkg/resolution/common" "github.com/tektoncd/pipeline/pkg/resolution/resource" "github.com/tektoncd/pipeline/test" "github.com/tektoncd/pipeline/test/diff" + resolution "github.com/tektoncd/pipeline/test/resolution" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/pkg/logging" _ "knative.dev/pkg/system/testing" // Setup system.Namespace() @@ -144,7 +145,7 @@ conditions: testCases := []struct { name string - inputRequest *test.RawRequest + inputRequest *resolution.RawRequest inputResolutionRequest *v1beta1.ResolutionRequest expectedResolutionRequest *v1beta1.ResolutionRequest expectedResolvedResource *v1beta1.ResolutionRequest @@ -156,7 +157,7 @@ conditions: inputResolutionRequest: nil, expectedResolutionRequest: createdRR.DeepCopy(), expectedResolvedResource: nil, - expectedErr: resolutioncommon.ErrRequestInProgress, + expectedErr: common.ErrRequestInProgress, }, { name: "resolution request exist and status is unknown", @@ -164,7 +165,7 @@ conditions: inputResolutionRequest: unknownRR.DeepCopy(), expectedResolutionRequest: nil, expectedResolvedResource: nil, - expectedErr: resolutioncommon.ErrRequestInProgress, + expectedErr: common.ErrRequestInProgress, }, { name: "resolution request exist and status is succeeded", @@ -188,7 +189,7 @@ conditions: inputResolutionRequest: failedRR.DeepCopy(), expectedResolutionRequest: nil, expectedResolvedResource: nil, - expectedErr: resolutioncommon.NewError(resolutioncommon.ReasonResolutionFailed, errors.New("error message")), + expectedErr: common.NewError(common.ReasonResolutionFailed, errors.New("error message")), }, } @@ -204,7 +205,7 @@ conditions: ctx := testAssets.Ctx clients := testAssets.Clients - resolver := resolutioncommon.ResolverName("git") + resolver := common.ResolverName("git") crdRequester := resource.NewCRDRequester(clients.ResolutionRequests, testAssets.Informers.ResolutionRequest.Lister()) requestWithOwner := &ownerRequest{ Request: tc.inputRequest.Request(), @@ -235,7 +236,7 @@ conditions: if err != nil { t.Errorf("unexpected error decoding expected resource data: %v", err) } - expectedResolvedResource := test.NewResolvedResource(data, rr.Status.Annotations, rr.Status.RefSource, nil) + expectedResolvedResource := resolution.NewResolvedResource(data, rr.Status.Annotations, rr.Status.RefSource, nil) assertResolvedResourceEqual(t, expectedResolvedResource, resolvedResource) } @@ -255,7 +256,7 @@ conditions: } type ownerRequest struct { - resolutioncommon.Request + common.Request ownerRef metav1.OwnerReference } @@ -263,9 +264,9 @@ func (r *ownerRequest) OwnerRef() metav1.OwnerReference { return r.ownerRef } -func mustParseRawRequest(t *testing.T, yamlStr string) *test.RawRequest { +func mustParseRawRequest(t *testing.T, yamlStr string) *resolution.RawRequest { t.Helper() - output := &test.RawRequest{} + output := &resolution.RawRequest{} if err := yaml.Unmarshal([]byte(yamlStr), output); err != nil { t.Errorf("parsing raw request %s: %v", yamlStr, err) } @@ -299,7 +300,7 @@ func mustParseResolutionRequestStatus(t *testing.T, yamlStr string) *v1beta1.Res return output } -func assertResolvedResourceEqual(t *testing.T, expected, actual resolutioncommon.ResolvedResource) { +func assertResolvedResourceEqual(t *testing.T, expected, actual common.ResolvedResource) { t.Helper() expectedBytes, err := expected.Data() if err != nil { diff --git a/pkg/resolution/resource/name.go b/pkg/resolution/resource/name.go index 051eabc89d0..eef3cb88afb 100644 --- a/pkg/resolution/resource/name.go +++ b/pkg/resolution/resource/name.go @@ -21,26 +21,64 @@ import ( "hash" "hash/fnv" "sort" + "strings" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" + "k8s.io/apimachinery/pkg/util/validation" + "knative.dev/pkg/kmeta" ) +const maxLength = validation.DNS1123LabelMaxLength + +// GenerateDeterministicName makes a best-effort attempt to create a +// unique but reproducible name for use in a Request. The returned value +// will have the format {prefix}-{hash} where {prefix} is +// given and {hash} is nameHasher(base) + nameHasher(param1) + +// nameHasher(param2) + ... +func GenerateDeterministicName(prefix, base string, params v1.Params) (string, error) { + return GenerateDeterministicNameFromSpec(prefix, base, &v1beta1.ResolutionRequestSpec{Params: params}) +} + +func GetNameAndNamespace(resolverName string, owner kmeta.OwnerRefable, name string, namespace string, params v1.Params) (string, string, error) { + if name == "" { + name = owner.GetObjectMeta().GetName() + namespace = owner.GetObjectMeta().GetNamespace() + } + if namespace == "" { + namespace = "default" + } + // Generating a deterministic name for the resource request + // prevents multiple requests being issued for the same + // pipelinerun's pipelineRef or taskrun's taskRef. + remoteResourceBaseName := namespace + "/" + name + name, err := GenerateDeterministicNameFromSpec(resolverName, remoteResourceBaseName, &v1beta1.ResolutionRequestSpec{Params: params}) + if err != nil { + return "", "", fmt.Errorf("error generating name for taskrun %s/%s: %w", namespace, name, err) + } + return name, namespace, nil +} + // nameHasher returns the hash.Hash to use when generating names. func nameHasher() hash.Hash { return fnv.New128a() } -// GenerateDeterministicName makes a best-effort attempt to create a +// GenerateDeterministicNameFromSpec makes a best-effort attempt to create a // unique but reproducible name for use in a Request. The returned value // will have the format {prefix}-{hash} where {prefix} is // given and {hash} is nameHasher(base) + nameHasher(param1) + // nameHasher(param2) + ... -func GenerateDeterministicName(prefix, base string, params v1.Params) (string, error) { +func GenerateDeterministicNameFromSpec(prefix, base string, resolutionSpec *v1beta1.ResolutionRequestSpec) (string, error) { hasher := nameHasher() if _, err := hasher.Write([]byte(base)); err != nil { return "", err } + if resolutionSpec == nil { + return fmt.Sprintf("%s-%x", prefix, hasher.Sum(nil)), nil + } + params := resolutionSpec.Params sortedParams := make(v1.Params, len(params)) for i := range params { sortedParams[i] = *params[i].DeepCopy() @@ -67,5 +105,9 @@ func GenerateDeterministicName(prefix, base string, params v1.Params) (string, e } } } - return fmt.Sprintf("%s-%x", prefix, hasher.Sum(nil)), nil + name := fmt.Sprintf("%s-%x", prefix, hasher.Sum(nil)) + if maxLength > len(name) { + return name, nil + } + return name[:strings.LastIndex(name[:maxLength], " ")], nil } diff --git a/pkg/resolution/resource/request.go b/pkg/resolution/resource/request.go index 9e0f3e194e7..792267ad36f 100644 --- a/pkg/resolution/resource/request.go +++ b/pkg/resolution/resource/request.go @@ -33,8 +33,6 @@ func NewRequest(name, namespace string, params v1.Params) Request { return &BasicRequest{name, namespace, params} } -var _ Request = &BasicRequest{} - // Name returns the name attached to the request func (req *BasicRequest) Name() string { return req.name diff --git a/test/remoteresolution/resolution.go b/test/remoteresolution/resolution.go new file mode 100644 index 00000000000..daefaed94ea --- /dev/null +++ b/test/remoteresolution/resolution.go @@ -0,0 +1,166 @@ +/* +Copyright 2024 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package test + +import ( + "context" + "errors" + "fmt" + "strings" + + "github.com/google/go-cmp/cmp" + pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + resource "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" + resolution "github.com/tektoncd/pipeline/pkg/resolution/common" + "github.com/tektoncd/pipeline/test/diff" +) + +var _ resource.Requester = &Requester{} +var _ resolution.ResolvedResource = &ResolvedResource{} + +// NewResolvedResource creates a mock resolved resource that is +// populated with the given data and annotations or returns the given +// error from its Data() method. +func NewResolvedResource(data []byte, annotations map[string]string, source *pipelinev1.RefSource, dataErr error) *ResolvedResource { + return &ResolvedResource{ + ResolvedData: data, + ResolvedAnnotations: annotations, + ResolvedRefSource: source, + DataErr: dataErr, + } +} + +// NewRequester creates a mock requester that resolves to the given +// resource or returns the given error on Submit(). +func NewRequester(resource resolution.ResolvedResource, err error, resolverPayload resource.ResolverPayload) *Requester { + return &Requester{ + ResolvedResource: resource, + SubmitErr: err, + ResolverPayload: resolverPayload, + } +} + +// Requester implements resolution.Requester and makes it easier +// to mock the outcome of a remote pipelineRef or taskRef resolution. +type Requester struct { + // The resolved resource object to return when a request is + // submitted. + ResolvedResource resolution.ResolvedResource + // An error to return when a request is submitted. + SubmitErr error + // ResolverPayload that should match that of the request in order to return the resolved resource + ResolverPayload resource.ResolverPayload +} + +// Submit implements resolution.Requester, accepting the name of a +// resolver and a request for a specific remote file, and then returns +// whatever mock data was provided on initialization. +func (r *Requester) Submit(ctx context.Context, resolverName resolution.ResolverName, req resource.Request) (resolution.ResolvedResource, error) { + if (r.ResolverPayload == resource.ResolverPayload{} || r.ResolverPayload.ResolutionSpec == nil || len(r.ResolverPayload.ResolutionSpec.Params) == 0) { + return r.ResolvedResource, r.SubmitErr + } + + reqParams := make(map[string]pipelinev1.ParamValue) + for _, p := range req.ResolverPayload().ResolutionSpec.Params { + reqParams[p.Name] = p.Value + } + + var wrongParams []string + for _, p := range r.ResolverPayload.ResolutionSpec.Params { + if reqValue, ok := reqParams[p.Name]; !ok { + wrongParams = append(wrongParams, fmt.Sprintf("expected %s param to be %#v, but was %#v", p.Name, p.Value, reqValue)) + } else if d := cmp.Diff(p.Value, reqValue); d != "" { + wrongParams = append(wrongParams, fmt.Sprintf("%s param did not match: %s", p.Name, diff.PrintWantGot(d))) + } + } + if len(wrongParams) > 0 { + return nil, errors.New(strings.Join(wrongParams, "; ")) + } + + return r.ResolvedResource, r.SubmitErr +} + +// ResolvedResource implements resolution.ResolvedResource and makes +// it easier to mock the resolved content of a fetched pipeline or task. +type ResolvedResource struct { + // The resolved bytes to return when resolution is complete. + ResolvedData []byte + // An error to return instead of the resolved bytes after + // resolution completes. + DataErr error + // Annotations to return when resolution is complete. + ResolvedAnnotations map[string]string + // ResolvedRefSource to return the source reference of the remote data + ResolvedRefSource *pipelinev1.RefSource +} + +// Data implements resolution.ResolvedResource and returns the mock +// data and/or error given to it on initialization. +func (r *ResolvedResource) Data() ([]byte, error) { + return r.ResolvedData, r.DataErr +} + +// Annotations implements resolution.ResolvedResource and returns +// the mock annotations given to it on initialization. +func (r *ResolvedResource) Annotations() map[string]string { + return r.ResolvedAnnotations +} + +// RefSource is the source reference of the remote data that records where the remote +// file came from including the url, digest and the entrypoint. +func (r *ResolvedResource) RefSource() *pipelinev1.RefSource { + return r.ResolvedRefSource +} + +// RawRequest stores the raw request data +type RawRequest struct { + ResolverPayload resource.ResolverPayload +} + +// Request returns a Request interface based on the RawRequest. +func (r *RawRequest) Request() resource.Request { + if r == nil { + r = &RawRequest{} + } + return &Request{ + RawRequest: *r, + } +} + +// Request implements resolution.Request and makes it easier to mock input for submit +// Using inline structs is to avoid conflicts between field names and method names. +type Request struct { + RawRequest +} + +var _ resource.Request = &Request{} + +// NewRequest creates a mock request that is populated with the given name namespace and params +func NewRequest(resolverPayload resource.ResolverPayload) *Request { + return &Request{ + RawRequest: RawRequest{ + ResolverPayload: resolverPayload, + }, + } +} + +// Params implements resolution.Request and returns the mock params given to it on initialization. +func (r *Request) ResolverPayload() resource.ResolverPayload { + return r.RawRequest.ResolverPayload +} + +var _ resource.Request = &Request{} diff --git a/test/resolution.go b/test/resolution/resolution.go similarity index 91% rename from test/resolution.go rename to test/resolution/resolution.go index 514988427f2..b8b940658f9 100644 --- a/test/resolution.go +++ b/test/resolution/resolution.go @@ -24,16 +24,16 @@ import ( "github.com/google/go-cmp/cmp" pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" - resolution "github.com/tektoncd/pipeline/pkg/resolution/common" + common "github.com/tektoncd/pipeline/pkg/resolution/common" "github.com/tektoncd/pipeline/test/diff" ) -var _ resolution.Requester = &Requester{} -var _ resolution.ResolvedResource = &ResolvedResource{} +var _ common.Requester = &Requester{} +var _ common.ResolvedResource = &ResolvedResource{} // NewRequester creates a mock requester that resolves to the given // resource or returns the given error on Submit(). -func NewRequester(resource resolution.ResolvedResource, err error) *Requester { +func NewRequester(resource common.ResolvedResource, err error) *Requester { return &Requester{ ResolvedResource: resource, SubmitErr: err, @@ -57,7 +57,7 @@ func NewResolvedResource(data []byte, annotations map[string]string, source *pip type Requester struct { // The resolved resource object to return when a request is // submitted. - ResolvedResource resolution.ResolvedResource + ResolvedResource common.ResolvedResource // An error to return when a request is submitted. SubmitErr error // Params that should match those on the request in order to return the resolved resource @@ -67,7 +67,7 @@ type Requester struct { // Submit implements resolution.Requester, accepting the name of a // resolver and a request for a specific remote file, and then returns // whatever mock data was provided on initialization. -func (r *Requester) Submit(ctx context.Context, resolverName resolution.ResolverName, req resolution.Request) (resolution.ResolvedResource, error) { +func (r *Requester) Submit(ctx context.Context, resolverName common.ResolverName, req common.Request) (common.ResolvedResource, error) { if len(r.Params) == 0 { return r.ResolvedResource, r.SubmitErr } @@ -134,7 +134,7 @@ type RawRequest struct { } // Request returns a Request interface based on the RawRequest. -func (r *RawRequest) Request() resolution.Request { +func (r *RawRequest) Request() common.Request { if r == nil { r = &RawRequest{} } @@ -149,7 +149,7 @@ type Request struct { RawRequest } -var _ resolution.Request = &Request{} +var _ common.Request = &Request{} // NewRequest creates a mock request that is populated with the given name namespace and params func NewRequest(name, namespace string, params []pipelinev1.Param) *Request { diff --git a/test/resolvers_test.go b/test/resolvers_test.go index 1979a1703c2..3829a84b647 100644 --- a/test/resolvers_test.go +++ b/test/resolvers_test.go @@ -37,7 +37,7 @@ import ( resolverconfig "github.com/tektoncd/pipeline/pkg/apis/config/resolver" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" "github.com/tektoncd/pipeline/pkg/reconciler/pipelinerun" - "github.com/tektoncd/pipeline/pkg/resolution/resolver/git" + gitresolution "github.com/tektoncd/pipeline/pkg/resolution/resolver/git" "github.com/tektoncd/pipeline/test/parse" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -484,24 +484,24 @@ func TestGitResolver_API(t *testing.T) { resovlerNS := resolverconfig.ResolversNamespace(systemNamespace) - originalConfigMap, err := c.KubeClient.CoreV1().ConfigMaps(resovlerNS).Get(ctx, git.ConfigMapName, metav1.GetOptions{}) + originalConfigMap, err := c.KubeClient.CoreV1().ConfigMaps(resovlerNS).Get(ctx, gitresolution.ConfigMapName, metav1.GetOptions{}) if err != nil { - t.Fatalf("Failed to get ConfigMap `%s`: %s", git.ConfigMapName, err) + t.Fatalf("Failed to get ConfigMap `%s`: %s", gitresolution.ConfigMapName, err) } originalConfigMapData := originalConfigMap.Data - t.Logf("Creating ConfigMap %s", git.ConfigMapName) + t.Logf("Creating ConfigMap %s", gitresolution.ConfigMapName) configMapData := map[string]string{ - git.ServerURLKey: fmt.Sprint("http://", net.JoinHostPort(giteaClusterHostname, "3000")), - git.SCMTypeKey: "gitea", - git.APISecretNameKey: tokenSecretName, - git.APISecretKeyKey: scmTokenSecretKey, - git.APISecretNamespaceKey: namespace, + gitresolution.ServerURLKey: fmt.Sprint("http://", net.JoinHostPort(giteaClusterHostname, "3000")), + gitresolution.SCMTypeKey: "gitea", + gitresolution.APISecretNameKey: tokenSecretName, + gitresolution.APISecretKeyKey: scmTokenSecretKey, + gitresolution.APISecretNamespaceKey: namespace, } - if err := updateConfigMap(ctx, c.KubeClient, resovlerNS, git.ConfigMapName, configMapData); err != nil { + if err := updateConfigMap(ctx, c.KubeClient, resovlerNS, gitresolution.ConfigMapName, configMapData); err != nil { t.Fatal(err) } - defer resetConfigMap(ctx, t, c, resovlerNS, git.ConfigMapName, originalConfigMapData) + defer resetConfigMap(ctx, t, c, resovlerNS, gitresolution.ConfigMapName, originalConfigMapData) trName := helpers.ObjectNameForTest(t) tr := parse.MustParseV1TaskRun(t, fmt.Sprintf(` From 2bd16b804785ba6f1f54387163d6d0fbf98a02ef Mon Sep 17 00:00:00 2001 From: Eric Zhang Date: Sat, 27 Apr 2024 13:14:23 -0400 Subject: [PATCH 03/23] misc: promote stepAction to beta --- cmd/webhook/main.go | 10 + config/300-crds/300-stepaction.yaml | 18 + docs/additional-configs.md | 2 +- docs/pipeline-api.md | 433 +++++++- docs/stepactions.md | 6 +- .../stepaction-git-resolver.yaml | 0 .../{alpha => beta}/stepaction-params.yaml | 2 +- .../stepaction-passing-results.yaml | 2 +- .../{alpha => beta}/stepaction-results.yaml | 2 +- .../taskruns/{alpha => beta}/stepaction.yaml | 2 +- pkg/apis/config/feature_flags.go | 4 +- pkg/apis/pipeline/v1/openapi_generated.go | 2 +- pkg/apis/pipeline/v1/result_types.go | 2 +- pkg/apis/pipeline/v1/swagger.json | 2 +- .../v1alpha1/stepaction_conversion.go | 53 +- .../v1alpha1/stepaction_conversion_test.go | 113 ++ .../pipeline/v1beta1/openapi_generated.go | 263 +++++ pkg/apis/pipeline/v1beta1/register.go | 2 + .../pipeline/v1beta1/stepaction_conversion.go | 42 + .../pipeline/v1beta1/stepaction_defaults.go | 37 + pkg/apis/pipeline/v1beta1/stepaction_types.go | 170 +++ .../pipeline/v1beta1/stepaction_validation.go | 209 ++++ .../v1beta1/stepaction_validation_test.go | 975 ++++++++++++++++++ pkg/apis/pipeline/v1beta1/swagger.json | 135 +++ .../pipeline/v1beta1/zz_generated.deepcopy.go | 119 +++ .../v1beta1/fake/fake_pipeline_client.go | 4 + .../pipeline/v1beta1/fake/fake_stepaction.go | 129 +++ .../pipeline/v1beta1/generated_expansion.go | 2 + .../typed/pipeline/v1beta1/pipeline_client.go | 5 + .../typed/pipeline/v1beta1/stepaction.go | 178 ++++ .../informers/externalversions/generic.go | 2 + .../pipeline/v1beta1/interface.go | 7 + .../pipeline/v1beta1/stepaction.go | 90 ++ .../pipeline/v1beta1/stepaction/fake/fake.go | 40 + .../v1beta1/stepaction/filtered/fake/fake.go | 52 + .../v1beta1/stepaction/filtered/stepaction.go | 65 ++ .../pipeline/v1beta1/stepaction/stepaction.go | 52 + .../pipeline/v1beta1/stepaction/controller.go | 167 +++ .../pipeline/v1beta1/stepaction/reconciler.go | 365 +++++++ .../pipeline/v1beta1/stepaction/state.go | 97 ++ .../pipeline/v1beta1/expansion_generated.go | 8 + .../listers/pipeline/v1beta1/stepaction.go | 99 ++ pkg/reconciler/apiserver/apiserver.go | 7 + pkg/reconciler/apiserver/apiserver_test.go | 7 + pkg/reconciler/taskrun/resources/taskref.go | 28 +- .../taskrun/resources/taskref_test.go | 28 +- pkg/reconciler/taskrun/resources/taskspec.go | 4 +- .../taskrun/resources/taskspec_test.go | 64 +- pkg/reconciler/taskrun/taskrun_test.go | 28 +- test/clients.go | 4 +- test/controller.go | 8 +- test/e2e-tests-kind-prow-beta.env | 1 + test/featureflags.go | 3 +- test/parse/yaml.go | 11 + test/per_feature_flags_test.go | 4 +- test/stepaction_results_test.go | 10 +- 56 files changed, 4076 insertions(+), 98 deletions(-) rename examples/v1/taskruns/{alpha => beta}/stepaction-git-resolver.yaml (100%) rename examples/v1/taskruns/{alpha => beta}/stepaction-params.yaml (98%) rename examples/v1/taskruns/{alpha => beta}/stepaction-passing-results.yaml (98%) rename examples/v1/taskruns/{alpha => beta}/stepaction-results.yaml (94%) rename examples/v1/taskruns/{alpha => beta}/stepaction.yaml (90%) create mode 100644 pkg/apis/pipeline/v1alpha1/stepaction_conversion_test.go create mode 100644 pkg/apis/pipeline/v1beta1/stepaction_conversion.go create mode 100644 pkg/apis/pipeline/v1beta1/stepaction_defaults.go create mode 100644 pkg/apis/pipeline/v1beta1/stepaction_types.go create mode 100644 pkg/apis/pipeline/v1beta1/stepaction_validation.go create mode 100644 pkg/apis/pipeline/v1beta1/stepaction_validation_test.go create mode 100644 pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_stepaction.go create mode 100644 pkg/client/clientset/versioned/typed/pipeline/v1beta1/stepaction.go create mode 100644 pkg/client/informers/externalversions/pipeline/v1beta1/stepaction.go create mode 100644 pkg/client/injection/informers/pipeline/v1beta1/stepaction/fake/fake.go create mode 100644 pkg/client/injection/informers/pipeline/v1beta1/stepaction/filtered/fake/fake.go create mode 100644 pkg/client/injection/informers/pipeline/v1beta1/stepaction/filtered/stepaction.go create mode 100644 pkg/client/injection/informers/pipeline/v1beta1/stepaction/stepaction.go create mode 100644 pkg/client/injection/reconciler/pipeline/v1beta1/stepaction/controller.go create mode 100644 pkg/client/injection/reconciler/pipeline/v1beta1/stepaction/reconciler.go create mode 100644 pkg/client/injection/reconciler/pipeline/v1beta1/stepaction/state.go create mode 100644 pkg/client/listers/pipeline/v1beta1/stepaction.go diff --git a/cmd/webhook/main.go b/cmd/webhook/main.go index 02128320bc1..7281f0af421 100644 --- a/cmd/webhook/main.go +++ b/cmd/webhook/main.go @@ -60,6 +60,7 @@ var types = map[schema.GroupVersionKind]resourcesemantics.GenericCRD{ v1beta1.SchemeGroupVersion.WithKind("TaskRun"): &v1beta1.TaskRun{}, v1beta1.SchemeGroupVersion.WithKind("PipelineRun"): &v1beta1.PipelineRun{}, v1beta1.SchemeGroupVersion.WithKind("CustomRun"): &v1beta1.CustomRun{}, + v1beta1.SchemeGroupVersion.WithKind("StepAction"): &v1beta1.StepAction{}, // v1 v1.SchemeGroupVersion.WithKind("Task"): &v1.Task{}, v1.SchemeGroupVersion.WithKind("Pipeline"): &v1.Pipeline{}, @@ -153,6 +154,7 @@ func newConfigValidationController(name string) func(context.Context, configmap. func newConversionController(ctx context.Context, cmw configmap.Watcher) *controller.Impl { var ( + v1alpha1GroupVersion = v1alpha1.SchemeGroupVersion.Version v1beta1GroupVersion = v1beta1.SchemeGroupVersion.Version v1GroupVersion = v1.SchemeGroupVersion.Version resolutionv1alpha1GroupVersion = resolutionv1alpha1.SchemeGroupVersion.Version @@ -170,6 +172,14 @@ func newConversionController(ctx context.Context, cmw configmap.Watcher) *contro // conversions to and from all types. // "Zygotes" are the supported versions. map[schema.GroupKind]conversion.GroupKindConversion{ + v1beta1.Kind("StepAction"): { + DefinitionName: pipeline.StepActionResource.String(), + HubVersion: v1alpha1GroupVersion, + Zygotes: map[string]conversion.ConvertibleObject{ + v1alpha1GroupVersion: &v1alpha1.StepAction{}, + v1beta1GroupVersion: &v1beta1.StepAction{}, + }, + }, v1.Kind("Task"): { DefinitionName: pipeline.TaskResource.String(), HubVersion: v1beta1GroupVersion, diff --git a/config/300-crds/300-stepaction.yaml b/config/300-crds/300-stepaction.yaml index a27eaf20179..5f91f9629b3 100644 --- a/config/300-crds/300-stepaction.yaml +++ b/config/300-crds/300-stepaction.yaml @@ -26,6 +26,24 @@ spec: preserveUnknownFields: false versions: - name: v1alpha1 + served: true + storage: false + schema: + openAPIV3Schema: + type: object + # One can use x-kubernetes-preserve-unknown-fields: true + # at the root of the schema (and inside any properties, additionalProperties) + # to get the traditional CRD behaviour that nothing is pruned, despite + # setting spec.preserveUnknownProperties: false. + # + # See https://kubernetes.io/blog/2019/06/20/crd-structural-schema/ + # See issue: https://github.com/knative/serving/issues/912 + x-kubernetes-preserve-unknown-fields: true + # Opt into the status subresource so metadata.generation + # starts to increment + subresources: + status: {} + - name: v1beta1 served: true storage: true schema: diff --git a/docs/additional-configs.md b/docs/additional-configs.md index be60c6c3b2d..417843a7105 100644 --- a/docs/additional-configs.md +++ b/docs/additional-configs.md @@ -384,7 +384,6 @@ Features currently in "alpha" are: | [keep pod on cancel](./taskruns.md#cancelling-a-taskrun) | N/A | [v0.52.0](https://github.com/tektoncd/pipeline/releases/tag/v0.52.0) | `keep-pod-on-cancel` | | [CEL in WhenExpression](./pipelines.md#use-cel-expression-in-whenexpression) | [TEP-0145](https://github.com/tektoncd/community/blob/main/teps/0145-cel-in-whenexpression.md) | [v0.53.0](https://github.com/tektoncd/pipeline/releases/tag/v0.53.0) | `enable-cel-in-whenexpression` | | [Param Enum](./taskruns.md#parameter-enums) | [TEP-0144](https://github.com/tektoncd/community/blob/main/teps/0144-param-enum.md) | [v0.54.0](https://github.com/tektoncd/pipeline/releases/tag/v0.54.0) | `enable-param-enum` | -| [Reusable Steps via StepActions](./stepactions.md) | [TEP-0142](https://github.com/tektoncd/community/blob/main/teps/0142-enable-step-reusability.md) | [v0.54.0](https://github.com/tektoncd/pipeline/releases/tag/v0.54.0) | `enable-step-actions` | | [Ignore Task Failure](./pipelines.md#using-the-onerror-field) | [TEP-0050](https://github.com/tektoncd/community/blob/main/teps/0050-ignore-task-failures.md) | N/A | | ### Beta Features @@ -403,6 +402,7 @@ Features currently in "beta" are: | [Isolated `Step` & `Sidecar` `Workspaces`](./workspaces.md#isolated-workspaces) | [TEP-0029](https://github.com/tektoncd/community/blob/main/teps/0029-step-workspaces.md) | [v0.24.0](https://github.com/tektoncd/pipeline/releases/tag/v0.24.0) | [v0.50.0](https://github.com/tektoncd/pipeline/releases/tag/v0.50.0) | | | [Matrix](./matrix.md) | [TEP-0090](https://github.com/tektoncd/community/blob/main/teps/0090-matrix.md) | [v0.38.0](https://github.com/tektoncd/pipeline/releases/tag/v0.38.0) | [v0.53.0](https://github.com/tektoncd/pipeline/releases/tag/v0.53.0) | | | [Task-level Resource Requirements](compute-resources.md#task-level-compute-resources-configuration) | [TEP-0104](https://github.com/tektoncd/community/blob/main/teps/0104-tasklevel-resource-requirements.md) | [v0.39.0](https://github.com/tektoncd/pipeline/releases/tag/v0.39.0) | [v0.53.0](https://github.com/tektoncd/pipeline/releases/tag/v0.53.0) | | +| [Reusable Steps via StepActions](./stepactions.md) | [TEP-0142](https://github.com/tektoncd/community/blob/main/teps/0142-enable-step-reusability.md) | [v0.54.0](https://github.com/tektoncd/pipeline/releases/tag/v0.54.0) | `enable-step-actions` | ## Enabling larger results using sidecar logs diff --git a/docs/pipeline-api.md b/docs/pipeline-api.md index c8e57271de6..ca3c9dd0b31 100644 --- a/docs/pipeline-api.md +++ b/docs/pipeline-api.md @@ -1852,7 +1852,7 @@ If Enum is not set, no input validation is performed for the param.

ParamSpecs ([]github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamSpec alias)

-(Appears on:PipelineSpec, TaskSpec, StepActionSpec) +(Appears on:PipelineSpec, TaskSpec, StepActionSpec, StepActionSpec)

ParamSpecs is a list of ParamSpec

@@ -4650,11 +4650,11 @@ string

StepResult

-(Appears on:Step, StepActionSpec, Step) +(Appears on:Step, StepActionSpec, Step, StepActionSpec)

StepResult used to describe the Results of a Step.

-

This is field is at an ALPHA stability level and gated by “enable-step-actions” feature flag.

+

This is field is at an BETA stability level and gated by “enable-step-actions” feature flag.

@@ -8363,6 +8363,8 @@ Resource Types:
  • PipelineRun
  • +StepAction +
  • Task
  • TaskRun @@ -9190,6 +9192,240 @@ PipelineRunStatus
  • +

    StepAction +

    +
    +

    StepAction represents the actionable components of Step. +The Step can only reference it from the cluster or using remote resolution.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +apiVersion
    +string
    + +tekton.dev/v1beta1 + +
    +kind
    +string +
    StepAction
    +metadata
    + + +Kubernetes meta/v1.ObjectMeta + + +
    +(Optional) +Refer to the Kubernetes API documentation for the fields of the +metadata field. +
    +spec
    + + +StepActionSpec + + +
    +(Optional) +

    Spec holds the desired state of the Step from the client

    +
    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    +description
    + +string + +
    +(Optional) +

    Description is a user-facing description of the stepaction that may be +used to populate a UI.

    +
    +image
    + +string + +
    +(Optional) +

    Image reference name to run for this StepAction. +More info: https://kubernetes.io/docs/concepts/containers/images

    +
    +command
    + +[]string + +
    +(Optional) +

    Entrypoint array. Not executed within a shell. +The image’s ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container’s environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. “$$(VAR_NAME)” will +produce the string literal “$(VAR_NAME)”. Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. +More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

    +
    +args
    + +[]string + +
    +(Optional) +

    Arguments to the entrypoint. +The image’s CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container’s environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. “$$(VAR_NAME)” will +produce the string literal “$(VAR_NAME)”. Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. +More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

    +
    +env
    + + +[]Kubernetes core/v1.EnvVar + + +
    +(Optional) +

    List of environment variables to set in the container. +Cannot be updated.

    +
    +script
    + +string + +
    +(Optional) +

    Script is the contents of an executable file to execute.

    +

    If Script is not empty, the Step cannot have an Command and the Args will be passed to the Script.

    +
    +workingDir
    + +string + +
    +(Optional) +

    Step’s working directory. +If not specified, the container runtime’s default will be used, which +might be configured in the container image. +Cannot be updated.

    +
    +params
    + + +ParamSpecs + + +
    +(Optional) +

    Params is a list of input parameters required to run the stepAction. +Params must be supplied as inputs in Steps unless they declare a defaultvalue.

    +
    +results
    + + +[]StepResult + + +
    +(Optional) +

    Results are values that this StepAction can output

    +
    +securityContext
    + + +Kubernetes core/v1.SecurityContext + + +
    +(Optional) +

    SecurityContext defines the security options the Step should be run with. +If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. +More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +The value set in StepAction will take precedence over the value from Task.

    +
    +volumeMounts
    + + +[]Kubernetes core/v1.VolumeMount + + +
    +(Optional) +

    Volumes to mount into the Step’s filesystem. +Cannot be updated.

    +
    +

    Task

    @@ -13802,6 +14038,197 @@ The Results declared by the StepActions will be stored here instead.

    +

    StepActionObject +

    +
    +

    StepActionObject is implemented by StepAction

    +
    +

    StepActionSpec +

    +

    +(Appears on:StepAction) +

    +
    +

    StepActionSpec contains the actionable components of a step.

    +
    + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
    FieldDescription
    +description
    + +string + +
    +(Optional) +

    Description is a user-facing description of the stepaction that may be +used to populate a UI.

    +
    +image
    + +string + +
    +(Optional) +

    Image reference name to run for this StepAction. +More info: https://kubernetes.io/docs/concepts/containers/images

    +
    +command
    + +[]string + +
    +(Optional) +

    Entrypoint array. Not executed within a shell. +The image’s ENTRYPOINT is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container’s environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. “$$(VAR_NAME)” will +produce the string literal “$(VAR_NAME)”. Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. +More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

    +
    +args
    + +[]string + +
    +(Optional) +

    Arguments to the entrypoint. +The image’s CMD is used if this is not provided. +Variable references $(VAR_NAME) are expanded using the container’s environment. If a variable +cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced +to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. “$$(VAR_NAME)” will +produce the string literal “$(VAR_NAME)”. Escaped references will never be expanded, regardless +of whether the variable exists or not. Cannot be updated. +More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell

    +
    +env
    + + +[]Kubernetes core/v1.EnvVar + + +
    +(Optional) +

    List of environment variables to set in the container. +Cannot be updated.

    +
    +script
    + +string + +
    +(Optional) +

    Script is the contents of an executable file to execute.

    +

    If Script is not empty, the Step cannot have an Command and the Args will be passed to the Script.

    +
    +workingDir
    + +string + +
    +(Optional) +

    Step’s working directory. +If not specified, the container runtime’s default will be used, which +might be configured in the container image. +Cannot be updated.

    +
    +params
    + + +ParamSpecs + + +
    +(Optional) +

    Params is a list of input parameters required to run the stepAction. +Params must be supplied as inputs in Steps unless they declare a defaultvalue.

    +
    +results
    + + +[]StepResult + + +
    +(Optional) +

    Results are values that this StepAction can output

    +
    +securityContext
    + + +Kubernetes core/v1.SecurityContext + + +
    +(Optional) +

    SecurityContext defines the security options the Step should be run with. +If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. +More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ +The value set in StepAction will take precedence over the value from Task.

    +
    +volumeMounts
    + + +[]Kubernetes core/v1.VolumeMount + + +
    +(Optional) +

    Volumes to mount into the Step’s filesystem. +Cannot be updated.

    +

    StepOutputConfig

    diff --git a/docs/stepactions.md b/docs/stepactions.md index afaa35ce003..c7d5a334035 100644 --- a/docs/stepactions.md +++ b/docs/stepactions.md @@ -22,7 +22,7 @@ weight: 201 - [Cannot pass Step Results between Steps](#cannot-pass-step-results-between-steps) ## Overview -> :seedling: **`StepActions` is an [alpha](additional-configs.md#alpha-features) feature.** +> :seedling: **`StepActions` is an [beta](additional-configs.md#beta-features) feature.** > The `enable-step-actions` feature flag must be set to `"true"` to specify a `StepAction` in a `Step`. A `StepAction` is the reusable and scriptable unit of work that is performed by a `Step`. @@ -62,7 +62,7 @@ A `StepAction` definition supports the following fields: The example below demonstrates the use of most of the above-mentioned fields: ```yaml -apiVersion: tekton.dev/v1alpha1 +apiVersion: tekton.dev/v1beta1 kind: StepAction metadata: name: example-stepaction-name @@ -82,7 +82,7 @@ Like with `Tasks`, a `StepAction` must declare all the parameters that it uses. `Parameters` are passed to the `StepAction` from its corresponding `Step` referencing it. ```yaml -apiVersion: tekton.dev/v1alpha1 +apiVersion: tekton.dev/v1beta1 kind: StepAction metadata: name: stepaction-using-params diff --git a/examples/v1/taskruns/alpha/stepaction-git-resolver.yaml b/examples/v1/taskruns/beta/stepaction-git-resolver.yaml similarity index 100% rename from examples/v1/taskruns/alpha/stepaction-git-resolver.yaml rename to examples/v1/taskruns/beta/stepaction-git-resolver.yaml diff --git a/examples/v1/taskruns/alpha/stepaction-params.yaml b/examples/v1/taskruns/beta/stepaction-params.yaml similarity index 98% rename from examples/v1/taskruns/alpha/stepaction-params.yaml rename to examples/v1/taskruns/beta/stepaction-params.yaml index 52402bbdfe6..1ae7a70c70f 100644 --- a/examples/v1/taskruns/alpha/stepaction-params.yaml +++ b/examples/v1/taskruns/beta/stepaction-params.yaml @@ -1,4 +1,4 @@ -apiVersion: tekton.dev/v1alpha1 +apiVersion: tekton.dev/v1beta1 kind: StepAction metadata: name: step-action diff --git a/examples/v1/taskruns/alpha/stepaction-passing-results.yaml b/examples/v1/taskruns/beta/stepaction-passing-results.yaml similarity index 98% rename from examples/v1/taskruns/alpha/stepaction-passing-results.yaml rename to examples/v1/taskruns/beta/stepaction-passing-results.yaml index e02a771c746..f8b1b011465 100644 --- a/examples/v1/taskruns/alpha/stepaction-passing-results.yaml +++ b/examples/v1/taskruns/beta/stepaction-passing-results.yaml @@ -1,4 +1,4 @@ -apiVersion: tekton.dev/v1alpha1 +apiVersion: tekton.dev/v1beta1 kind: StepAction metadata: name: step-action diff --git a/examples/v1/taskruns/alpha/stepaction-results.yaml b/examples/v1/taskruns/beta/stepaction-results.yaml similarity index 94% rename from examples/v1/taskruns/alpha/stepaction-results.yaml rename to examples/v1/taskruns/beta/stepaction-results.yaml index 7ea048830a7..e922b1d7718 100644 --- a/examples/v1/taskruns/alpha/stepaction-results.yaml +++ b/examples/v1/taskruns/beta/stepaction-results.yaml @@ -1,4 +1,4 @@ -apiVersion: tekton.dev/v1alpha1 +apiVersion: tekton.dev/v1beta1 kind: StepAction metadata: name: step-action diff --git a/examples/v1/taskruns/alpha/stepaction.yaml b/examples/v1/taskruns/beta/stepaction.yaml similarity index 90% rename from examples/v1/taskruns/alpha/stepaction.yaml rename to examples/v1/taskruns/beta/stepaction.yaml index 3acc1e263f4..93feb955705 100644 --- a/examples/v1/taskruns/alpha/stepaction.yaml +++ b/examples/v1/taskruns/beta/stepaction.yaml @@ -1,4 +1,4 @@ -apiVersion: tekton.dev/v1alpha1 +apiVersion: tekton.dev/v1beta1 kind: StepAction metadata: name: step-action diff --git a/pkg/apis/config/feature_flags.go b/pkg/apis/config/feature_flags.go index 66fdeb5c7ad..326a33aebcf 100644 --- a/pkg/apis/config/feature_flags.go +++ b/pkg/apis/config/feature_flags.go @@ -151,8 +151,8 @@ var ( // DefaultEnableStepActions is the default PerFeatureFlag value for EnableStepActions DefaultEnableStepActions = PerFeatureFlag{ Name: EnableStepActions, - Stability: AlphaAPIFields, - Enabled: DefaultAlphaFeatureEnabled, + Stability: BetaAPIFields, + Enabled: DefaultBetaFeatureEnabled, } // DefaultEnableArtifacts is the default PerFeatureFlag value for EnableArtifacts diff --git a/pkg/apis/pipeline/v1/openapi_generated.go b/pkg/apis/pipeline/v1/openapi_generated.go index f9380013f7d..a5b1eff4048 100644 --- a/pkg/apis/pipeline/v1/openapi_generated.go +++ b/pkg/apis/pipeline/v1/openapi_generated.go @@ -3159,7 +3159,7 @@ func schema_pkg_apis_pipeline_v1_StepResult(ref common.ReferenceCallback) common return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ - Description: "StepResult used to describe the Results of a Step.\n\nThis is field is at an ALPHA stability level and gated by \"enable-step-actions\" feature flag.", + Description: "StepResult used to describe the Results of a Step.\n\nThis is field is at an BETA stability level and gated by \"enable-step-actions\" feature flag.", Type: []string{"object"}, Properties: map[string]spec.Schema{ "name": { diff --git a/pkg/apis/pipeline/v1/result_types.go b/pkg/apis/pipeline/v1/result_types.go index 6361d7a362d..b36bf6fc658 100644 --- a/pkg/apis/pipeline/v1/result_types.go +++ b/pkg/apis/pipeline/v1/result_types.go @@ -40,7 +40,7 @@ type TaskResult struct { // StepResult used to describe the Results of a Step. // -// This is field is at an ALPHA stability level and gated by "enable-step-actions" feature flag. +// This is field is at an BETA stability level and gated by "enable-step-actions" feature flag. type StepResult struct { // Name the given name Name string `json:"name"` diff --git a/pkg/apis/pipeline/v1/swagger.json b/pkg/apis/pipeline/v1/swagger.json index 8993af2ffff..b44c5d35645 100644 --- a/pkg/apis/pipeline/v1/swagger.json +++ b/pkg/apis/pipeline/v1/swagger.json @@ -1611,7 +1611,7 @@ } }, "v1.StepResult": { - "description": "StepResult used to describe the Results of a Step.\n\nThis is field is at an ALPHA stability level and gated by \"enable-step-actions\" feature flag.", + "description": "StepResult used to describe the Results of a Step.\n\nThis is field is at an BETA stability level and gated by \"enable-step-actions\" feature flag.", "type": "object", "required": [ "name" diff --git a/pkg/apis/pipeline/v1alpha1/stepaction_conversion.go b/pkg/apis/pipeline/v1alpha1/stepaction_conversion.go index a02bf76096a..b2896d0de8f 100644 --- a/pkg/apis/pipeline/v1alpha1/stepaction_conversion.go +++ b/pkg/apis/pipeline/v1alpha1/stepaction_conversion.go @@ -15,7 +15,9 @@ package v1alpha1 import ( "context" + "fmt" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" "knative.dev/pkg/apis" ) @@ -23,20 +25,63 @@ var _ apis.Convertible = (*StepAction)(nil) // ConvertTo implements apis.Convertible func (s *StepAction) ConvertTo(ctx context.Context, to apis.Convertible) error { - return nil + if apis.IsInDelete(ctx) { + return nil + } + switch sink := to.(type) { + case *v1beta1.StepAction: + sink.ObjectMeta = s.ObjectMeta + return s.Spec.ConvertTo(ctx, &sink.Spec) + default: + return fmt.Errorf("unknown version, got: %T", sink) + } } // ConvertTo implements apis.Convertible -func (ss *StepActionSpec) ConvertTo(ctx context.Context, sink *StepActionSpec) error { +func (ss *StepActionSpec) ConvertTo(ctx context.Context, sink *v1beta1.StepActionSpec) error { + sink.Description = ss.Description + sink.Image = ss.Image + sink.Command = ss.Command + sink.Args = ss.Args + sink.Env = ss.Env + sink.Script = ss.Script + sink.WorkingDir = ss.WorkingDir + sink.Params = ss.Params + sink.Results = ss.Results + sink.SecurityContext = ss.SecurityContext + sink.VolumeMounts = ss.VolumeMounts + return nil } // ConvertFrom implements apis.Convertible func (s *StepAction) ConvertFrom(ctx context.Context, from apis.Convertible) error { - return nil + if apis.IsInDelete(ctx) { + return nil + } + switch source := from.(type) { + case *v1beta1.StepAction: + s.ObjectMeta = source.ObjectMeta + return s.Spec.ConvertFrom(ctx, &source.Spec) + default: + return fmt.Errorf("unknown version, got: %T", source) + } } // ConvertFrom implements apis.Convertible -func (ss *StepActionSpec) ConvertFrom(ctx context.Context, source *StepActionSpec) error { +func (ss *StepActionSpec) ConvertFrom(ctx context.Context, source *v1beta1.StepActionSpec) error { + ss.Description = source.Description + ss.Image = source.Image + ss.Command = source.Command + ss.Args = source.Args + ss.Env = source.Env + ss.Script = source.Script + ss.WorkingDir = source.WorkingDir + + ss.Params = source.Params + ss.Results = source.Results + ss.SecurityContext = source.SecurityContext + ss.VolumeMounts = source.VolumeMounts + return nil } diff --git a/pkg/apis/pipeline/v1alpha1/stepaction_conversion_test.go b/pkg/apis/pipeline/v1alpha1/stepaction_conversion_test.go new file mode 100644 index 00000000000..9193b6e7b32 --- /dev/null +++ b/pkg/apis/pipeline/v1alpha1/stepaction_conversion_test.go @@ -0,0 +1,113 @@ +package v1alpha1_test + +import ( + "context" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + "github.com/tektoncd/pipeline/test/diff" + "github.com/tektoncd/pipeline/test/parse" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +func TestPipelineConversionBadType(t *testing.T) { + good, bad := &v1alpha1.StepAction{}, &v1beta1.Task{} + + if err := good.ConvertTo(context.Background(), bad); err == nil { + t.Errorf("ConvertTo() = %#v, wanted error", bad) + } + + if err := good.ConvertFrom(context.Background(), bad); err == nil { + t.Errorf("ConvertFrom() = %#v, wanted error", good) + } +} + +func TestStepActionConversion(t *testing.T) { + stepActionWithAllFieldsYaml := ` +metadata: + name: foo + namespace: bar +spec: + name: all-fields + image: foo + command: ["hello"] + args: ["world"] + results: + - name: result1 + - name: result2 + script: | + echo "I am a Step Action!!!" >> $(step.results.result1.path) + echo "I am a hidden step action!!!" >> $(step.results.result2.path) + workingDir: "/dir" + envFrom: + - prefix: prefix + params: + - name: string-param + type: string + default: "a string param" + - name: array-param + type: array + default: + - an + - array + - param + - name: object-param + type: object + properties: + key1: + type: string + key2: + type: string + key3: + type: string + default: + key1: "step-action default key1" + key2: "step-action default key2" + key3: "step-action default key3" + volumeMounts: + - name: data + mountPath: /data + securityContext: + privileged: true +` + + stepActionV1alpha1 := parse.MustParseV1alpha1StepAction(t, stepActionWithAllFieldsYaml) + stepActionV1beta1 := parse.MustParseV1beta1StepAction(t, stepActionWithAllFieldsYaml) + + var ignoreTypeMeta = cmpopts.IgnoreFields(metav1.TypeMeta{}, "Kind", "APIVersion") + + tests := []struct { + name string + v1AlphaStepAction *v1alpha1.StepAction + v1Beta1StepAction *v1beta1.StepAction + }{{ + name: "stepAction conversion with all fields", + v1AlphaStepAction: stepActionV1alpha1, + v1Beta1StepAction: stepActionV1beta1, + }} + + for _, test := range tests { + t.Run(test.name, func(t *testing.T) { + v1Beta1StepAction := &v1beta1.StepAction{} + if err := test.v1AlphaStepAction.ConvertTo(context.Background(), v1Beta1StepAction); err != nil { + t.Errorf("ConvertTo() = %v", err) + return + } + t.Logf("ConvertTo() = %#v", v1Beta1StepAction) + if d := cmp.Diff(test.v1Beta1StepAction, v1Beta1StepAction, ignoreTypeMeta); d != "" { + t.Errorf("expected v1Task is different from what's converted: %s", d) + } + gotV1alpha1 := &v1alpha1.StepAction{} + if err := gotV1alpha1.ConvertFrom(context.Background(), v1Beta1StepAction); err != nil { + t.Errorf("ConvertFrom() = %v", err) + } + t.Logf("ConvertFrom() = %#v", gotV1alpha1) + if d := cmp.Diff(test.v1AlphaStepAction, gotV1alpha1, ignoreTypeMeta); d != "" { + t.Errorf("roundtrip %s", diff.PrintWantGot(d)) + } + }) + } +} diff --git a/pkg/apis/pipeline/v1beta1/openapi_generated.go b/pkg/apis/pipeline/v1beta1/openapi_generated.go index d938565b86d..a5199123b74 100644 --- a/pkg/apis/pipeline/v1beta1/openapi_generated.go +++ b/pkg/apis/pipeline/v1beta1/openapi_generated.go @@ -87,6 +87,9 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.SidecarState": schema_pkg_apis_pipeline_v1beta1_SidecarState(ref), "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.SkippedTask": schema_pkg_apis_pipeline_v1beta1_SkippedTask(ref), "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.Step": schema_pkg_apis_pipeline_v1beta1_Step(ref), + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepAction": schema_pkg_apis_pipeline_v1beta1_StepAction(ref), + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepActionList": schema_pkg_apis_pipeline_v1beta1_StepActionList(ref), + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepActionSpec": schema_pkg_apis_pipeline_v1beta1_StepActionSpec(ref), "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepOutputConfig": schema_pkg_apis_pipeline_v1beta1_StepOutputConfig(ref), "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepState": schema_pkg_apis_pipeline_v1beta1_StepState(ref), "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepTemplate": schema_pkg_apis_pipeline_v1beta1_StepTemplate(ref), @@ -4088,6 +4091,266 @@ func schema_pkg_apis_pipeline_v1beta1_Step(ref common.ReferenceCallback) common. } } +func schema_pkg_apis_pipeline_v1beta1_StepAction(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "StepAction represents the actionable components of Step. The Step can only reference it from the cluster or using remote resolution.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"), + }, + }, + "spec": { + SchemaProps: spec.SchemaProps{ + Description: "Spec holds the desired state of the Step from the client", + Default: map[string]interface{}{}, + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepActionSpec"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepActionSpec", "k8s.io/apimachinery/pkg/apis/meta/v1.ObjectMeta"}, + } +} + +func schema_pkg_apis_pipeline_v1beta1_StepActionList(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "StepActionList contains a list of StepActions", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "kind": { + SchemaProps: spec.SchemaProps{ + Description: "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + Type: []string{"string"}, + Format: "", + }, + }, + "apiVersion": { + SchemaProps: spec.SchemaProps{ + Description: "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + Type: []string{"string"}, + Format: "", + }, + }, + "metadata": { + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"), + }, + }, + "items": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepAction"), + }, + }, + }, + }, + }, + }, + Required: []string{"items"}, + }, + }, + Dependencies: []string{ + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1.StepAction", "k8s.io/apimachinery/pkg/apis/meta/v1.ListMeta"}, + } +} + +func schema_pkg_apis_pipeline_v1beta1_StepActionSpec(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "StepActionSpec contains the actionable components of a step.", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "description": { + SchemaProps: spec.SchemaProps{ + Description: "Description is a user-facing description of the stepaction that may be used to populate a UI.", + Type: []string{"string"}, + Format: "", + }, + }, + "image": { + SchemaProps: spec.SchemaProps{ + Description: "Image reference name to run for this StepAction. More info: https://kubernetes.io/docs/concepts/containers/images", + Type: []string{"string"}, + Format: "", + }, + }, + "command": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Entrypoint array. Not executed within a shell. The image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "args": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "env": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "List of environment variables to set in the container. Cannot be updated.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.EnvVar"), + }, + }, + }, + }, + }, + "script": { + SchemaProps: spec.SchemaProps{ + Description: "Script is the contents of an executable file to execute.\n\nIf Script is not empty, the Step cannot have an Command and the Args will be passed to the Script.", + Type: []string{"string"}, + Format: "", + }, + }, + "workingDir": { + SchemaProps: spec.SchemaProps{ + Description: "Step's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", + Type: []string{"string"}, + Format: "", + }, + }, + "params": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Params is a list of input parameters required to run the stepAction. Params must be supplied as inputs in Steps unless they declare a defaultvalue.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamSpec"), + }, + }, + }, + }, + }, + "results": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Results are values that this StepAction can output", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepResult"), + }, + }, + }, + }, + }, + "securityContext": { + SchemaProps: spec.SchemaProps{ + Description: "SecurityContext defines the security options the Step should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ The value set in StepAction will take precedence over the value from Task.", + Ref: ref("k8s.io/api/core/v1.SecurityContext"), + }, + }, + "volumeMounts": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-list-type": "atomic", + "x-kubernetes-patch-merge-key": "mountPath", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "Volumes to mount into the Step's filesystem. Cannot be updated.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.VolumeMount"), + }, + }, + }, + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.ParamSpec", "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1.StepResult", "k8s.io/api/core/v1.EnvVar", "k8s.io/api/core/v1.SecurityContext", "k8s.io/api/core/v1.VolumeMount"}, + } +} + func schema_pkg_apis_pipeline_v1beta1_StepOutputConfig(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/pkg/apis/pipeline/v1beta1/register.go b/pkg/apis/pipeline/v1beta1/register.go index 6154ae5dad5..c33fa8a848b 100644 --- a/pkg/apis/pipeline/v1beta1/register.go +++ b/pkg/apis/pipeline/v1beta1/register.go @@ -58,6 +58,8 @@ func addKnownTypes(scheme *runtime.Scheme) error { &PipelineRunList{}, &CustomRun{}, &CustomRunList{}, + &StepAction{}, + &StepActionList{}, ) // &Condition{}, // &ConditionList{}, diff --git a/pkg/apis/pipeline/v1beta1/stepaction_conversion.go b/pkg/apis/pipeline/v1beta1/stepaction_conversion.go new file mode 100644 index 00000000000..6d8afd26f33 --- /dev/null +++ b/pkg/apis/pipeline/v1beta1/stepaction_conversion.go @@ -0,0 +1,42 @@ +/* +Copyright 2023 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "context" + + "knative.dev/pkg/apis" +) + +var _ apis.Convertible = (*StepAction)(nil) + +// ConvertTo implements apis.Convertible +func (s *StepAction) ConvertTo(ctx context.Context, to apis.Convertible) error { + return nil +} + +// ConvertTo implements apis.Convertible +func (ss *StepActionSpec) ConvertTo(ctx context.Context, sink *StepActionSpec) error { + return nil +} + +// ConvertFrom implements apis.Convertible +func (s *StepAction) ConvertFrom(ctx context.Context, from apis.Convertible) error { + return nil +} + +// ConvertFrom implements apis.Convertible +func (ss *StepActionSpec) ConvertFrom(ctx context.Context, source *StepActionSpec) error { + return nil +} diff --git a/pkg/apis/pipeline/v1beta1/stepaction_defaults.go b/pkg/apis/pipeline/v1beta1/stepaction_defaults.go new file mode 100644 index 00000000000..0274a66bc2e --- /dev/null +++ b/pkg/apis/pipeline/v1beta1/stepaction_defaults.go @@ -0,0 +1,37 @@ +/* +Copyright 2023 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "context" + + "knative.dev/pkg/apis" +) + +var _ apis.Defaultable = (*StepAction)(nil) + +// SetDefaults implements apis.Defaultable +func (s *StepAction) SetDefaults(ctx context.Context) { + s.Spec.SetDefaults(ctx) +} + +// SetDefaults set any defaults for the StepAction spec +func (ss *StepActionSpec) SetDefaults(ctx context.Context) { + for i := range ss.Params { + ss.Params[i].SetDefaults(ctx) + } + for i := range ss.Results { + ss.Results[i].SetDefaults(ctx) + } +} diff --git a/pkg/apis/pipeline/v1beta1/stepaction_types.go b/pkg/apis/pipeline/v1beta1/stepaction_types.go new file mode 100644 index 00000000000..495c9ee010d --- /dev/null +++ b/pkg/apis/pipeline/v1beta1/stepaction_types.go @@ -0,0 +1,170 @@ +/* +Copyright 2023 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/apimachinery/pkg/runtime/schema" + "knative.dev/pkg/apis" + "knative.dev/pkg/kmeta" +) + +// +genclient +// +genclient:noStatus +// +genreconciler:krshapedlogic=false +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object + +// StepAction represents the actionable components of Step. +// The Step can only reference it from the cluster or using remote resolution. +// +// +k8s:openapi-gen=true +type StepAction struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ObjectMeta `json:"metadata"` + + // Spec holds the desired state of the Step from the client + // +optional + Spec StepActionSpec `json:"spec"` +} + +var _ kmeta.OwnerRefable = (*StepAction)(nil) + +// StepAction returns the step action's spec +func (s *StepAction) StepActionSpec() StepActionSpec { + return s.Spec +} + +// StepActionMetadata returns the step action's ObjectMeta +func (s *StepAction) StepActionMetadata() metav1.ObjectMeta { + return s.ObjectMeta +} + +// Copy returns a deep copy of the stepaction +func (s *StepAction) Copy() StepActionObject { + return s.DeepCopy() +} + +// GetGroupVersionKind implements kmeta.OwnerRefable. +func (*StepAction) GetGroupVersionKind() schema.GroupVersionKind { + return SchemeGroupVersion.WithKind("StepAction") +} + +// StepActionList contains a list of StepActions +// +k8s:deepcopy-gen:interfaces=k8s.io/apimachinery/pkg/runtime.Object +type StepActionList struct { + metav1.TypeMeta `json:",inline"` + // +optional + metav1.ListMeta `json:"metadata,omitempty"` + Items []StepAction `json:"items"` +} + +// StepActionSpec contains the actionable components of a step. +type StepActionSpec struct { + // Description is a user-facing description of the stepaction that may be + // used to populate a UI. + // +optional + Description string `json:"description,omitempty"` + // Image reference name to run for this StepAction. + // More info: https://kubernetes.io/docs/concepts/containers/images + // +optional + Image string `json:"image,omitempty" protobuf:"bytes,2,opt,name=image"` + // Entrypoint array. Not executed within a shell. + // The image's ENTRYPOINT is used if this is not provided. + // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + // cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + // to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + // produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + // of whether the variable exists or not. Cannot be updated. + // More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + // +optional + // +listType=atomic + Command []string `json:"command,omitempty" protobuf:"bytes,3,rep,name=command"` + // Arguments to the entrypoint. + // The image's CMD is used if this is not provided. + // Variable references $(VAR_NAME) are expanded using the container's environment. If a variable + // cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced + // to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. "$$(VAR_NAME)" will + // produce the string literal "$(VAR_NAME)". Escaped references will never be expanded, regardless + // of whether the variable exists or not. Cannot be updated. + // More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell + // +optional + // +listType=atomic + Args []string `json:"args,omitempty" protobuf:"bytes,4,rep,name=args"` + // List of environment variables to set in the container. + // Cannot be updated. + // +optional + // +patchMergeKey=name + // +patchStrategy=merge + // +listType=atomic + Env []corev1.EnvVar `json:"env,omitempty" patchMergeKey:"name" patchStrategy:"merge" protobuf:"bytes,7,rep,name=env"` + // Script is the contents of an executable file to execute. + // + // If Script is not empty, the Step cannot have an Command and the Args will be passed to the Script. + // +optional + Script string `json:"script,omitempty"` + // Step's working directory. + // If not specified, the container runtime's default will be used, which + // might be configured in the container image. + // Cannot be updated. + // +optional + WorkingDir string `json:"workingDir,omitempty" protobuf:"bytes,5,opt,name=workingDir"` + // Params is a list of input parameters required to run the stepAction. + // Params must be supplied as inputs in Steps unless they declare a defaultvalue. + // +optional + // +listType=atomic + Params v1.ParamSpecs `json:"params,omitempty"` + // Results are values that this StepAction can output + // +optional + // +listType=atomic + Results []v1.StepResult `json:"results,omitempty"` + // SecurityContext defines the security options the Step should be run with. + // If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. + // More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ + // The value set in StepAction will take precedence over the value from Task. + // +optional + SecurityContext *corev1.SecurityContext `json:"securityContext,omitempty" protobuf:"bytes,15,opt,name=securityContext"` + // Volumes to mount into the Step's filesystem. + // Cannot be updated. + // +optional + // +patchMergeKey=mountPath + // +patchStrategy=merge + // +listType=atomic + VolumeMounts []corev1.VolumeMount `json:"volumeMounts,omitempty" patchMergeKey:"mountPath" patchStrategy:"merge" protobuf:"bytes,9,rep,name=volumeMounts"` +} + +// ToStep converts the StepActionSpec to a Step struct +func (ss *StepActionSpec) ToStep() *v1.Step { + return &v1.Step{ + Image: ss.Image, + Command: ss.Command, + Args: ss.Args, + WorkingDir: ss.WorkingDir, + Script: ss.Script, + Env: ss.Env, + VolumeMounts: ss.VolumeMounts, + SecurityContext: ss.SecurityContext, + Results: ss.Results, + } +} + +// StepActionObject is implemented by StepAction +type StepActionObject interface { + apis.Defaultable + StepActionMetadata() metav1.ObjectMeta + StepActionSpec() StepActionSpec + Copy() StepActionObject +} diff --git a/pkg/apis/pipeline/v1beta1/stepaction_validation.go b/pkg/apis/pipeline/v1beta1/stepaction_validation.go new file mode 100644 index 00000000000..0955c7e4f70 --- /dev/null +++ b/pkg/apis/pipeline/v1beta1/stepaction_validation.go @@ -0,0 +1,209 @@ +/* +Copyright 2023 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1 + +import ( + "context" + "strings" + + "github.com/tektoncd/pipeline/pkg/apis/config" + v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "github.com/tektoncd/pipeline/pkg/apis/validate" + "github.com/tektoncd/pipeline/pkg/substitution" + admissionregistrationv1 "k8s.io/api/admissionregistration/v1" + corev1 "k8s.io/api/core/v1" + "k8s.io/apimachinery/pkg/util/sets" + "knative.dev/pkg/apis" + "knative.dev/pkg/webhook/resourcesemantics" +) + +var ( + _ apis.Validatable = (*StepAction)(nil) + _ resourcesemantics.VerbLimited = (*StepAction)(nil) +) + +// SupportedVerbs returns the operations that validation should be called for +func (s *StepAction) SupportedVerbs() []admissionregistrationv1.OperationType { + return []admissionregistrationv1.OperationType{admissionregistrationv1.Create, admissionregistrationv1.Update} +} + +// Validate implements apis.Validatable +func (s *StepAction) Validate(ctx context.Context) (errs *apis.FieldError) { + errs = validate.ObjectMetadata(s.GetObjectMeta()).ViaField("metadata") + errs = errs.Also(s.Spec.Validate(apis.WithinSpec(ctx)).ViaField("spec")) + return errs +} + +// Validate implements apis.Validatable +func (ss *StepActionSpec) Validate(ctx context.Context) (errs *apis.FieldError) { + if ss.Image == "" { + errs = errs.Also(apis.ErrMissingField("Image")) + } + + if ss.Script != "" { + if len(ss.Command) > 0 { + errs = errs.Also(&apis.FieldError{ + Message: "script cannot be used with command", + Paths: []string{"script"}, + }) + } + + cleaned := strings.TrimSpace(ss.Script) + if strings.HasPrefix(cleaned, "#!win") { + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "windows script support", config.AlphaAPIFields).ViaField("script")) + } + errs = errs.Also(validateNoParamSubstitutionsInScript(ss.Script)) + } + errs = errs.Also(validateUsageOfDeclaredParameters(ctx, *ss)) + errs = errs.Also(v1.ValidateParameterTypes(ctx, ss.Params).ViaField("params")) + errs = errs.Also(validateParameterVariables(ctx, *ss, ss.Params)) + errs = errs.Also(v1.ValidateStepResultsVariables(ctx, ss.Results, ss.Script)) + errs = errs.Also(v1.ValidateStepResults(ctx, ss.Results).ViaField("results")) + errs = errs.Also(validateVolumeMounts(ss.VolumeMounts, ss.Params).ViaField("volumeMounts")) + return errs +} + +// validateNoParamSubstitutionsInScript validates that param substitutions are not invoked in the script +func validateNoParamSubstitutionsInScript(script string) *apis.FieldError { + _, present, errString := substitution.ExtractVariablesFromString(script, "params") + if errString != "" || present { + return &apis.FieldError{ + Message: "param substitution in scripts is not allowed.", + Paths: []string{"script"}, + } + } + return nil +} + +// validateUsageOfDeclaredParameters validates that all parameters referenced in the Task are declared by the Task. +func validateUsageOfDeclaredParameters(ctx context.Context, sas StepActionSpec) *apis.FieldError { + params := sas.Params + var errs *apis.FieldError + _, _, objectParams := params.SortByType() + allParameterNames := sets.NewString(params.GetNames()...) + errs = errs.Also(validateStepActionVariables(ctx, sas, "params", allParameterNames)) + errs = errs.Also(ValidateObjectUsage(ctx, sas, objectParams)) + errs = errs.Also(v1.ValidateObjectParamsHaveProperties(ctx, params)) + return errs +} + +func validateVolumeMounts(volumeMounts []corev1.VolumeMount, params v1.ParamSpecs) (errs *apis.FieldError) { + if len(volumeMounts) == 0 { + return + } + paramNames := sets.String{} + for _, p := range params { + paramNames.Insert(p.Name) + } + for idx, v := range volumeMounts { + matches, _ := substitution.ExtractVariableExpressions(v.Name, "params") + if len(matches) != 1 { + errs = errs.Also(apis.ErrInvalidValue(v.Name, "name", "expect the Name to be a single param reference").ViaIndex(idx)) + return errs + } else if matches[0] != v.Name { + errs = errs.Also(apis.ErrInvalidValue(v.Name, "name", "expect the Name to be a single param reference").ViaIndex(idx)) + return errs + } + errs = errs.Also(substitution.ValidateNoReferencesToUnknownVariables(v.Name, "params", paramNames).ViaIndex(idx)) + } + return errs +} + +// validateParameterVariables validates all variables within a slice of ParamSpecs against a StepAction +func validateParameterVariables(ctx context.Context, sas StepActionSpec, params v1.ParamSpecs) *apis.FieldError { + var errs *apis.FieldError + errs = errs.Also(params.ValidateNoDuplicateNames()) + stringParams, arrayParams, objectParams := params.SortByType() + stringParameterNames := sets.NewString(stringParams.GetNames()...) + arrayParameterNames := sets.NewString(arrayParams.GetNames()...) + errs = errs.Also(v1.ValidateNameFormat(stringParameterNames.Insert(arrayParameterNames.List()...), objectParams)) + return errs.Also(validateStepActionArrayUsage(sas, "params", arrayParameterNames)) +} + +// ValidateObjectUsage validates the usage of individual attributes of an object param and the usage of the entire object +func ValidateObjectUsage(ctx context.Context, sas StepActionSpec, params v1.ParamSpecs) (errs *apis.FieldError) { + objectParameterNames := sets.NewString() + for _, p := range params { + // collect all names of object type params + objectParameterNames.Insert(p.Name) + + // collect all keys for this object param + objectKeys := sets.NewString() + for key := range p.Properties { + objectKeys.Insert(key) + } + + // check if the object's key names are referenced correctly i.e. param.objectParam.key1 + errs = errs.Also(validateStepActionVariables(ctx, sas, "params\\."+p.Name, objectKeys)) + } + + return errs.Also(validateStepActionObjectUsageAsWhole(sas, "params", objectParameterNames)) +} + +// validateStepActionObjectUsageAsWhole returns an error if the StepAction contains references to the entire input object params in fields where these references are prohibited +func validateStepActionObjectUsageAsWhole(sas StepActionSpec, prefix string, vars sets.String) *apis.FieldError { + errs := substitution.ValidateNoReferencesToEntireProhibitedVariables(sas.Image, prefix, vars).ViaField("image") + errs = errs.Also(substitution.ValidateNoReferencesToEntireProhibitedVariables(sas.Script, prefix, vars).ViaField("script")) + for i, cmd := range sas.Command { + errs = errs.Also(substitution.ValidateNoReferencesToEntireProhibitedVariables(cmd, prefix, vars).ViaFieldIndex("command", i)) + } + for i, arg := range sas.Args { + errs = errs.Also(substitution.ValidateNoReferencesToEntireProhibitedVariables(arg, prefix, vars).ViaFieldIndex("args", i)) + } + for _, env := range sas.Env { + errs = errs.Also(substitution.ValidateNoReferencesToEntireProhibitedVariables(env.Value, prefix, vars).ViaFieldKey("env", env.Name)) + } + for i, vm := range sas.VolumeMounts { + errs = errs.Also(substitution.ValidateNoReferencesToEntireProhibitedVariables(vm.Name, prefix, vars).ViaFieldIndex("volumeMounts", i)) + } + return errs +} + +// validateStepActionArrayUsage returns an error if the Step contains references to the input array params in fields where these references are prohibited +func validateStepActionArrayUsage(sas StepActionSpec, prefix string, arrayParamNames sets.String) *apis.FieldError { + errs := substitution.ValidateNoReferencesToProhibitedVariables(sas.Image, prefix, arrayParamNames).ViaField("image") + errs = errs.Also(substitution.ValidateNoReferencesToProhibitedVariables(sas.Script, prefix, arrayParamNames).ViaField("script")) + for i, cmd := range sas.Command { + errs = errs.Also(substitution.ValidateVariableReferenceIsIsolated(cmd, prefix, arrayParamNames).ViaFieldIndex("command", i)) + } + for i, arg := range sas.Args { + errs = errs.Also(substitution.ValidateVariableReferenceIsIsolated(arg, prefix, arrayParamNames).ViaFieldIndex("args", i)) + } + for _, env := range sas.Env { + errs = errs.Also(substitution.ValidateNoReferencesToProhibitedVariables(env.Value, prefix, arrayParamNames).ViaFieldKey("env", env.Name)) + } + for i, vm := range sas.VolumeMounts { + errs = errs.Also(substitution.ValidateNoReferencesToProhibitedVariables(vm.Name, prefix, arrayParamNames).ViaFieldIndex("volumeMounts", i)) + } + return errs +} + +// validateStepActionVariables returns an error if the StepAction contains references to any unknown variables +func validateStepActionVariables(ctx context.Context, sas StepActionSpec, prefix string, vars sets.String) *apis.FieldError { + errs := substitution.ValidateNoReferencesToUnknownVariables(sas.Image, prefix, vars).ViaField("image") + errs = errs.Also(substitution.ValidateNoReferencesToUnknownVariables(sas.Script, prefix, vars).ViaField("script")) + for i, cmd := range sas.Command { + errs = errs.Also(substitution.ValidateNoReferencesToUnknownVariables(cmd, prefix, vars).ViaFieldIndex("command", i)) + } + for i, arg := range sas.Args { + errs = errs.Also(substitution.ValidateNoReferencesToUnknownVariables(arg, prefix, vars).ViaFieldIndex("args", i)) + } + for _, env := range sas.Env { + errs = errs.Also(substitution.ValidateNoReferencesToUnknownVariables(env.Value, prefix, vars).ViaFieldKey("env", env.Name)) + } + for i, vm := range sas.VolumeMounts { + errs = errs.Also(substitution.ValidateNoReferencesToUnknownVariables(vm.Name, prefix, vars).ViaFieldIndex("volumeMounts", i)) + } + return errs +} diff --git a/pkg/apis/pipeline/v1beta1/stepaction_validation_test.go b/pkg/apis/pipeline/v1beta1/stepaction_validation_test.go new file mode 100644 index 00000000000..49efacdf91a --- /dev/null +++ b/pkg/apis/pipeline/v1beta1/stepaction_validation_test.go @@ -0,0 +1,975 @@ +/* +Copyright 2023 The Tekton Authors +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + http://www.apache.org/licenses/LICENSE-2.0 +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1beta1_test + +import ( + "context" + "fmt" + "testing" + + "github.com/google/go-cmp/cmp" + "github.com/google/go-cmp/cmp/cmpopts" + v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + "github.com/tektoncd/pipeline/test/diff" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "knative.dev/pkg/apis" +) + +func TestStepActionValidate(t *testing.T) { + tests := []struct { + name string + sa *v1beta1.StepAction + wc func(context.Context) context.Context + }{{ + name: "valid step action", + sa: &v1beta1.StepAction{ + ObjectMeta: metav1.ObjectMeta{Name: "stepaction"}, + Spec: v1beta1.StepActionSpec{ + Image: "my-image", + Script: ` + #!/usr/bin/env bash + echo hello`, + }, + }, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + ctx := context.Background() + if tt.wc != nil { + ctx = tt.wc(ctx) + } + err := tt.sa.Validate(ctx) + if err != nil { + t.Errorf("StepAction.Validate() returned error for valid StepAction: %v", err) + } + }) + } +} + +func TestStepActionSpecValidate(t *testing.T) { + type fields struct { + Image string + Command []string + Args []string + Script string + Env []corev1.EnvVar + Params []v1.ParamSpec + Results []v1.StepResult + VolumeMounts []corev1.VolumeMount + } + tests := []struct { + name string + fields fields + }{{ + name: "step action with command", + fields: fields{ + Image: "myimage", + Command: []string{"ls"}, + Args: []string{"-lh"}, + }, + }, { + name: "step action with script", + fields: fields{ + Image: "myimage", + Script: "echo hi", + }, + }, { + name: "step action with env", + fields: fields{ + Image: "myimage", + Script: "echo hi", + Env: []corev1.EnvVar{{ + Name: "HOME", + Value: "/tekton/home", + }}, + }, + }, { + name: "valid params type explicit", + fields: fields{ + Image: "myimage", + Params: []v1.ParamSpec{{ + Name: "stringParam", + Type: v1.ParamTypeString, + Description: "param", + Default: v1.NewStructuredValues("default"), + }, { + Name: "objectParam", + Type: v1.ParamTypeObject, + Description: "param", + Properties: map[string]v1.PropertySpec{ + "key1": {}, + "key2": {}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "var1", + "key2": "var2", + }), + }, { + Name: "objectParamWithoutDefault", + Type: v1.ParamTypeObject, + Description: "param", + Properties: map[string]v1.PropertySpec{ + "key1": {}, + "key2": {}, + }, + }, { + Name: "objectParamWithDefaultPartialKeys", + Type: v1.ParamTypeObject, + Description: "param", + Properties: map[string]v1.PropertySpec{ + "key1": {}, + "key2": {}, + }, + Default: v1.NewObject(map[string]string{ + "key1": "default", + }), + }}, + }, + }, { + name: "valid string param usage", + fields: fields{ + Image: "url", + Params: []v1.ParamSpec{{ + Name: "baz", + }, { + Name: "foo-is-baz", + }}, + Args: []string{"--flag=$(params.baz) && $(params.foo-is-baz)"}, + }, + }, { + name: "valid array param usage", + fields: fields{ + Image: "url", + Params: []v1.ParamSpec{{ + Name: "baz", + Type: v1.ParamTypeArray, + }, { + Name: "foo-is-baz", + Type: v1.ParamTypeArray, + }}, + Command: []string{"$(params.foo-is-baz)"}, + Args: []string{"$(params.baz)", "middle string", "$(params.foo-is-baz)"}, + }, + }, { + name: "valid object param usage", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "gitrepo", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "url": {}, + "commit": {}, + }, + }}, + Image: "some-git-image", + Args: []string{"-url=$(params.gitrepo.url)", "-commit=$(params.gitrepo.commit)"}, + }, + }, { + name: "valid star array usage", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "baz", + Type: v1.ParamTypeArray, + }, { + Name: "foo-is-baz", + Type: v1.ParamTypeArray, + }}, + Image: "myimage", + Command: []string{"$(params.foo-is-baz)"}, + Args: []string{"$(params.baz[*])", "middle string", "$(params.foo-is-baz[*])"}, + }, + }, { + name: "valid result", + fields: fields{ + Image: "my-image", + Args: []string{"arg"}, + Results: []v1.StepResult{{ + Name: "MY-RESULT", + Description: "my great result", + }}, + }, + }, { + name: "valid result type string", + fields: fields{ + Image: "my-image", + Args: []string{"arg"}, + Results: []v1.StepResult{{ + Name: "MY-RESULT", + Type: "string", + Description: "my great result", + }}, + }, + }, { + name: "valid result type array", + fields: fields{ + Image: "my-image", + Args: []string{"arg"}, + Results: []v1.StepResult{{ + Name: "MY-RESULT", + Type: v1.ResultsTypeArray, + Description: "my great result", + }}, + }, + }, { + name: "valid result type object", + fields: fields{ + Image: "my-image", + Args: []string{"arg"}, + Results: []v1.StepResult{{ + Name: "MY-RESULT", + Type: v1.ResultsTypeObject, + Description: "my great result", + Properties: map[string]v1.PropertySpec{ + "url": {Type: "string"}, + "commit": {Type: "string"}, + }, + }}, + }, + }, { + name: "valid volumeMounts", + fields: fields{ + Image: "my-image", + Args: []string{"arg"}, + Params: []v1.ParamSpec{{ + Name: "foo", + }, { + Name: "array-params", + Type: v1.ParamTypeArray, + }, { + Name: "object-params", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "key": {Type: "string"}, + }, + }, + }, + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(params.foo)", + MountPath: "/config", + }, { + Name: "$(params.array-params[0])", + MountPath: "/config", + }, { + Name: "$(params.object-params.key)", + MountPath: "/config", + }}, + }, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + sa := &v1beta1.StepActionSpec{ + Image: tt.fields.Image, + Command: tt.fields.Command, + Args: tt.fields.Args, + Script: tt.fields.Script, + Env: tt.fields.Env, + Params: tt.fields.Params, + Results: tt.fields.Results, + VolumeMounts: tt.fields.VolumeMounts, + } + ctx := context.Background() + sa.SetDefaults(ctx) + if err := sa.Validate(ctx); err != nil { + t.Errorf("StepActionSpec.Validate() = %v", err) + } + }) + } +} + +func TestStepActionValidateError(t *testing.T) { + type fields struct { + Image string + Command []string + Args []string + Script string + Env []corev1.EnvVar + Params []v1.ParamSpec + Results []v1.StepResult + VolumeMounts []corev1.VolumeMount + } + tests := []struct { + name string + fields fields + expectedError apis.FieldError + }{{ + name: "inexistent image field", + fields: fields{ + Args: []string{"flag"}, + }, + expectedError: apis.FieldError{ + Message: `missing field(s)`, + Paths: []string{"spec.Image"}, + }, + }, { + name: "object used in a string field", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "gitrepo", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "url": {}, + "commit": {}, + }, + }}, + Image: "$(params.gitrepo)", + Args: []string{"echo"}, + }, + expectedError: apis.FieldError{ + Message: `variable type invalid in "$(params.gitrepo)"`, + Paths: []string{"spec.image"}, + }, + }, { + name: "object star used in a string field", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "gitrepo", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "url": {}, + "commit": {}, + }, + }}, + Image: "$(params.gitrepo[*])", + Args: []string{"echo"}, + }, + expectedError: apis.FieldError{ + Message: `variable type invalid in "$(params.gitrepo[*])"`, + Paths: []string{"spec.image"}, + }, + }, { + name: "object used in a field that can accept array type", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "gitrepo", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "url": {}, + "commit": {}, + }, + }}, + Image: "myimage", + Args: []string{"$(params.gitrepo)"}, + }, + expectedError: apis.FieldError{ + Message: `variable type invalid in "$(params.gitrepo)"`, + Paths: []string{"spec.args[0]"}, + }, + }, { + name: "object star used in a field that can accept array type", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "gitrepo", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "url": {}, + "commit": {}, + }, + }}, + Image: "some-git-image", + Args: []string{"$(params.gitrepo[*])"}, + }, + expectedError: apis.FieldError{ + Message: `variable type invalid in "$(params.gitrepo[*])"`, + Paths: []string{"spec.args[0]"}, + }, + }, { + name: "non-existent individual key of an object param is used in task step", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "gitrepo", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "url": {}, + "commit": {}, + }, + }}, + Image: "some-git-image", + Args: []string{"$(params.gitrepo.non-exist-key)"}, + }, + expectedError: apis.FieldError{ + Message: `non-existent variable in "$(params.gitrepo.non-exist-key)"`, + Paths: []string{"spec.args[0]"}, + }, + }, { + name: "Inexistent param variable with existing", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "foo", + Description: "param", + Default: v1.NewStructuredValues("default"), + }}, + Image: "myimage", + Args: []string{"$(params.foo) && $(params.inexistent)"}, + }, + expectedError: apis.FieldError{ + Message: `non-existent variable in "$(params.foo) && $(params.inexistent)"`, + Paths: []string{"spec.args[0]"}, + }, + }, { + name: "invalid param reference in volumeMount.Name - not a param reference", + fields: fields{ + Image: "myimage", + Params: []v1.ParamSpec{{ + Name: "foo", + }}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "params.foo", + MountPath: "/path", + }}, + }, + expectedError: apis.FieldError{ + Message: `invalid value: params.foo`, + Paths: []string{"spec.volumeMounts[0].name"}, + Details: `expect the Name to be a single param reference`, + }, + }, { + name: "invalid param reference in volumeMount.Name - nested reference", + fields: fields{ + Image: "myimage", + Params: []v1.ParamSpec{{ + Name: "foo", + }}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(params.foo)-foo", + MountPath: "/path", + }}, + }, + expectedError: apis.FieldError{ + Message: `invalid value: $(params.foo)-foo`, + Paths: []string{"spec.volumeMounts[0].name"}, + Details: `expect the Name to be a single param reference`, + }, + }, { + name: "invalid param reference in volumeMount.Name - multiple params references", + fields: fields{ + Image: "myimage", + Params: []v1.ParamSpec{{ + Name: "foo", + }, { + Name: "bar", + }}, + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(params.foo)$(params.bar)", + MountPath: "/path", + }}, + }, + expectedError: apis.FieldError{ + Message: `invalid value: $(params.foo)$(params.bar)`, + Paths: []string{"spec.volumeMounts[0].name"}, + Details: `expect the Name to be a single param reference`, + }, + }, { + name: "invalid param reference in volumeMount.Name - not defined in params", + fields: fields{ + Image: "myimage", + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(params.foo)", + MountPath: "/path", + }}, + }, + expectedError: apis.FieldError{ + Message: `non-existent variable in "$(params.foo)"`, + Paths: []string{"spec.volumeMounts[0]"}, + }, + }, { + name: "invalid param reference in volumeMount.Name - array used in a volumeMounts name field", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "gitrepo", + Type: v1.ParamTypeArray, + }}, + Image: "image", + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(params.gitrepo)", + }}, + }, + expectedError: apis.FieldError{ + Message: `variable type invalid in "$(params.gitrepo)"`, + Paths: []string{"spec.volumeMounts[0]"}, + }, + }, { + name: "invalid param reference in volumeMount.Name - object used in a volumeMounts name field", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "gitrepo", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "url": {}, + "commit": {}, + }, + }}, + Image: "image", + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(params.gitrepo)", + }}, + }, + expectedError: apis.FieldError{ + Message: `variable type invalid in "$(params.gitrepo)"`, + Paths: []string{"spec.volumeMounts[0]"}, + }, + }, { + name: "invalid param reference in volumeMount.Name - object key not existent in params", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "gitrepo", + Type: v1.ParamTypeObject, + Properties: map[string]v1.PropertySpec{ + "url": {}, + "commit": {}, + }, + }}, + Image: "image", + VolumeMounts: []corev1.VolumeMount{{ + Name: "$(params.gitrepo.foo)", + }}, + }, + expectedError: apis.FieldError{ + Message: `non-existent variable in "$(params.gitrepo.foo)"`, + Paths: []string{"spec.volumeMounts[0]"}, + }, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + sa := &v1beta1.StepAction{ + ObjectMeta: metav1.ObjectMeta{Name: "foo"}, + Spec: v1beta1.StepActionSpec{ + Image: tt.fields.Image, + Command: tt.fields.Command, + Args: tt.fields.Args, + Script: tt.fields.Script, + Env: tt.fields.Env, + Params: tt.fields.Params, + Results: tt.fields.Results, + VolumeMounts: tt.fields.VolumeMounts, + }, + } + ctx := context.Background() + sa.SetDefaults(ctx) + err := sa.Validate(ctx) + if err == nil { + t.Fatalf("Expected an error, got nothing for %v", sa) + } + if d := cmp.Diff(tt.expectedError.Error(), err.Error(), cmpopts.IgnoreUnexported(apis.FieldError{})); d != "" { + t.Errorf("StepActionSpec.Validate() errors diff %s", diff.PrintWantGot(d)) + } + }) + } +} + +func TestStepActionSpecValidateError(t *testing.T) { + type fields struct { + Image string + Command []string + Args []string + Script string + Env []corev1.EnvVar + Params []v1.ParamSpec + Results []v1.StepResult + } + tests := []struct { + name string + fields fields + expectedError apis.FieldError + }{{ + name: "inexistent image field", + fields: fields{ + Args: []string{"flag"}, + }, + expectedError: apis.FieldError{ + Message: `missing field(s)`, + Paths: []string{"Image"}, + }, + }, { + name: "command and script both used.", + fields: fields{ + Image: "my-image", + Command: []string{"ls"}, + Script: "echo hi", + }, + expectedError: apis.FieldError{ + Message: `script cannot be used with command`, + Paths: []string{"script"}, + }, + }, { + name: "windows script without alpha.", + fields: fields{ + Image: "my-image", + Script: "#!win", + }, + expectedError: apis.FieldError{ + Message: `windows script support requires "enable-api-fields" feature gate to be "alpha" but it is "beta"`, + Paths: []string{}, + }, + }, { + name: "step script refers to nonexistent result", + fields: fields{ + Image: "my-image", + Script: ` + #!/usr/bin/env bash + date | tee $(results.non-exist.path)`, + Results: []v1.StepResult{{Name: "a-result"}}, + }, + expectedError: apis.FieldError{ + Message: `non-existent variable in "\n\t\t\t#!/usr/bin/env bash\n\t\t\tdate | tee $(results.non-exist.path)"`, + Paths: []string{"script"}, + }, + }, { + name: "step script refers to nonexistent stepresult", + fields: fields{ + Image: "my-image", + Script: ` + #!/usr/bin/env bash + date | tee $(step.results.non-exist.path)`, + Results: []v1.StepResult{{Name: "a-result"}}, + }, + expectedError: apis.FieldError{ + Message: `non-existent variable in "\n\t\t\t#!/usr/bin/env bash\n\t\t\tdate | tee $(step.results.non-exist.path)"`, + Paths: []string{"script"}, + }, + }, { + name: "invalid param name format", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "_validparam1", + Description: "valid param name format", + }, { + Name: "valid_param2", + Description: "valid param name format", + }, { + Name: "", + Description: "invalid param name format", + }, { + Name: "a^b", + Description: "invalid param name format", + }, { + Name: "0ab", + Description: "invalid param name format", + }, { + Name: "f oo", + Description: "invalid param name format", + }}, + Image: "myImage", + }, + expectedError: apis.FieldError{ + Message: fmt.Sprintf("The format of following array and string variable names is invalid: %s", []string{"", "0ab", "a^b", "f oo"}), + Paths: []string{"params"}, + Details: "String/Array Names: \nMust only contain alphanumeric characters, hyphens (-), underscores (_), and dots (.)\nMust begin with a letter or an underscore (_)", + }, + }, { + name: "invalid object param format - object param name and key name shouldn't contain dots.", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "invalid.name1", + Description: "object param name contains dots", + Properties: map[string]v1.PropertySpec{ + "invalid.key1": {}, + "mykey2": {}, + }, + }}, + Image: "myImage", + }, + expectedError: apis.FieldError{ + Message: fmt.Sprintf("Object param name and key name format is invalid: %v", map[string][]string{ + "invalid.name1": {"invalid.key1"}, + }), + Paths: []string{"params"}, + Details: "Object Names: \nMust only contain alphanumeric characters, hyphens (-), underscores (_) \nMust begin with a letter or an underscore (_)", + }, + }, { + name: "duplicated param names", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "foo", + Type: v1.ParamTypeString, + Description: "parameter", + Default: v1.NewStructuredValues("value1"), + }, { + Name: "foo", + Type: v1.ParamTypeString, + Description: "parameter", + Default: v1.NewStructuredValues("value2"), + }}, + Image: "myImage", + }, + expectedError: apis.FieldError{ + Message: `parameter appears more than once`, + Paths: []string{"params[foo]"}, + }, + }, { + name: "invalid param type", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "validparam", + Type: v1.ParamTypeString, + Description: "parameter", + Default: v1.NewStructuredValues("default"), + }, { + Name: "param-with-invalid-type", + Type: "invalidtype", + Description: "invalidtypedesc", + Default: v1.NewStructuredValues("default"), + }}, + Image: "myImage", + }, + expectedError: apis.FieldError{ + Message: `invalid value: invalidtype`, + Paths: []string{"params.param-with-invalid-type.type"}, + }, + }, { + name: "param mismatching default/type 1", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "task", + Type: v1.ParamTypeArray, + Description: "param", + Default: v1.NewStructuredValues("default"), + }}, + Image: "myImage", + }, + expectedError: apis.FieldError{ + Message: `"array" type does not match default value's type: "string"`, + Paths: []string{"params.task.type", "params.task.default.type"}, + }, + }, { + name: "param mismatching default/type 2", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "task", + Type: v1.ParamTypeString, + Description: "param", + Default: v1.NewStructuredValues("default", "array"), + }}, + Image: "myImage", + }, + expectedError: apis.FieldError{ + Message: `"string" type does not match default value's type: "array"`, + Paths: []string{"params.task.type", "params.task.default.type"}, + }, + }, { + name: "param mismatching default/type 3", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "task", + Type: v1.ParamTypeArray, + Description: "param", + Default: v1.NewObject(map[string]string{ + "key1": "var1", + "key2": "var2", + }), + }}, + Image: "myImage", + }, + expectedError: apis.FieldError{ + Message: `"array" type does not match default value's type: "object"`, + Paths: []string{"params.task.type", "params.task.default.type"}, + }, + }, { + name: "param mismatching default/type 4", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "task", + Type: v1.ParamTypeObject, + Description: "param", + Properties: map[string]v1.PropertySpec{"key1": {}}, + Default: v1.NewStructuredValues("var"), + }}, + Image: "myImage", + }, + expectedError: apis.FieldError{ + Message: `"object" type does not match default value's type: "string"`, + Paths: []string{"params.task.type", "params.task.default.type"}, + }, + }, { + name: "PropertySpec type is set with unsupported type", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "task", + Type: v1.ParamTypeObject, + Description: "param", + Properties: map[string]v1.PropertySpec{ + "key1": {Type: "number"}, + "key2": {Type: "string"}, + }, + }}, + Image: "myImage", + }, + expectedError: apis.FieldError{ + Message: fmt.Sprintf("The value type specified for these keys %v is invalid", []string{"key1"}), + Paths: []string{"params.task.properties"}, + }, + }, { + name: "Properties is missing", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "task", + Type: v1.ParamTypeObject, + Description: "param", + }}, + Image: "myImage", + }, + expectedError: apis.FieldError{ + Message: "missing field(s)", + Paths: []string{"task.properties"}, + }, + }, { + name: "array used in unaccepted field", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "baz", + Type: v1.ParamTypeArray, + }, { + Name: "foo-is-baz", + Type: v1.ParamTypeArray, + }}, + Image: "$(params.baz)", + Command: []string{"$(params.foo-is-baz)"}, + Args: []string{"$(params.baz)", "middle string", "url"}, + }, + expectedError: apis.FieldError{ + Message: `variable type invalid in "$(params.baz)"`, + Paths: []string{"image"}, + }, + }, { + name: "array star used in unaccepted field", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "baz", + Type: v1.ParamTypeArray, + }, { + Name: "foo-is-baz", + Type: v1.ParamTypeArray, + }}, + Image: "$(params.baz[*])", + Command: []string{"$(params.foo-is-baz)"}, + Args: []string{"$(params.baz)", "middle string", "url"}, + }, + expectedError: apis.FieldError{ + Message: `variable type invalid in "$(params.baz[*])"`, + Paths: []string{"image"}, + }, + }, { + name: "array not properly isolated", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "baz", + Type: v1.ParamTypeArray, + }, { + Name: "foo-is-baz", + Type: v1.ParamTypeArray, + }}, + Image: "someimage", + Command: []string{"$(params.foo-is-baz)"}, + Args: []string{"not isolated: $(params.baz)", "middle string", "url"}, + }, + expectedError: apis.FieldError{ + Message: `variable is not properly isolated in "not isolated: $(params.baz)"`, + Paths: []string{"args[0]"}, + }, + }, { + name: "array star not properly isolated", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "baz", + Type: v1.ParamTypeArray, + }, { + Name: "foo-is-baz", + Type: v1.ParamTypeArray, + }}, + Image: "someimage", + Command: []string{"$(params.foo-is-baz)"}, + Args: []string{"not isolated: $(params.baz[*])", "middle string", "url"}, + }, + expectedError: apis.FieldError{ + Message: `variable is not properly isolated in "not isolated: $(params.baz[*])"`, + Paths: []string{"args[0]"}, + }, + }, { + name: "inferred array not properly isolated", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "baz", + Default: v1.NewStructuredValues("implied", "array", "type"), + }, { + Name: "foo-is-baz", + Default: v1.NewStructuredValues("implied", "array", "type"), + }}, + Image: "someimage", + Command: []string{"$(params.foo-is-baz)"}, + Args: []string{"not isolated: $(params.baz)", "middle string", "url"}, + }, + expectedError: apis.FieldError{ + Message: `variable is not properly isolated in "not isolated: $(params.baz)"`, + Paths: []string{"args[0]"}, + }, + }, { + name: "inferred array star not properly isolated", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "baz", + Default: v1.NewStructuredValues("implied", "array", "type"), + }, { + Name: "foo-is-baz", + Default: v1.NewStructuredValues("implied", "array", "type"), + }}, + Image: "someimage", + Command: []string{"$(params.foo-is-baz)"}, + Args: []string{"not isolated: $(params.baz[*])", "middle string", "url"}, + }, + expectedError: apis.FieldError{ + Message: `variable is not properly isolated in "not isolated: $(params.baz[*])"`, + Paths: []string{"args[0]"}, + }, + }, { + name: "params used in script field", + fields: fields{ + Params: []v1.ParamSpec{{ + Name: "baz", + Type: v1.ParamTypeArray, + }, { + Name: "foo-is-baz", + Type: v1.ParamTypeString, + }}, + Script: "$(params.baz[0]), $(params.foo-is-baz)", + Image: "my-image", + }, + expectedError: apis.FieldError{ + Message: `param substitution in scripts is not allowed.`, + Paths: []string{"script"}, + }, + }} + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + sa := v1beta1.StepActionSpec{ + Image: tt.fields.Image, + Command: tt.fields.Command, + Args: tt.fields.Args, + Script: tt.fields.Script, + Env: tt.fields.Env, + Params: tt.fields.Params, + Results: tt.fields.Results, + } + ctx := context.Background() + sa.SetDefaults(ctx) + err := sa.Validate(ctx) + if err == nil { + t.Fatalf("Expected an error, got nothing for %v", sa) + } + if d := cmp.Diff(tt.expectedError.Error(), err.Error(), cmpopts.IgnoreUnexported(apis.FieldError{})); d != "" { + t.Errorf("StepActionSpec.Validate() errors diff %s", diff.PrintWantGot(d)) + } + }) + } +} diff --git a/pkg/apis/pipeline/v1beta1/swagger.json b/pkg/apis/pipeline/v1beta1/swagger.json index 622b1d680c3..261b6878662 100644 --- a/pkg/apis/pipeline/v1beta1/swagger.json +++ b/pkg/apis/pipeline/v1beta1/swagger.json @@ -2255,6 +2255,141 @@ } } }, + "v1beta1.StepAction": { + "description": "StepAction represents the actionable components of Step. The Step can only reference it from the cluster or using remote resolution.", + "type": "object", + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "default": {}, + "$ref": "#/definitions/v1.ObjectMeta" + }, + "spec": { + "description": "Spec holds the desired state of the Step from the client", + "default": {}, + "$ref": "#/definitions/v1beta1.StepActionSpec" + } + } + }, + "v1beta1.StepActionList": { + "description": "StepActionList contains a list of StepActions", + "type": "object", + "required": [ + "items" + ], + "properties": { + "apiVersion": { + "description": "APIVersion defines the versioned schema of this representation of an object. Servers should convert recognized schemas to the latest internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources", + "type": "string" + }, + "items": { + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/v1beta1.StepAction" + } + }, + "kind": { + "description": "Kind is a string value representing the REST resource this object represents. Servers may infer this from the endpoint the client submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds", + "type": "string" + }, + "metadata": { + "default": {}, + "$ref": "#/definitions/v1.ListMeta" + } + } + }, + "v1beta1.StepActionSpec": { + "description": "StepActionSpec contains the actionable components of a step.", + "type": "object", + "properties": { + "args": { + "description": "Arguments to the entrypoint. The image's CMD is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + "type": "array", + "items": { + "type": "string", + "default": "" + }, + "x-kubernetes-list-type": "atomic" + }, + "command": { + "description": "Entrypoint array. Not executed within a shell. The image's ENTRYPOINT is used if this is not provided. Variable references $(VAR_NAME) are expanded using the container's environment. If a variable cannot be resolved, the reference in the input string will be unchanged. Double $$ are reduced to a single $, which allows for escaping the $(VAR_NAME) syntax: i.e. \"$$(VAR_NAME)\" will produce the string literal \"$(VAR_NAME)\". Escaped references will never be expanded, regardless of whether the variable exists or not. Cannot be updated. More info: https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#running-a-command-in-a-shell", + "type": "array", + "items": { + "type": "string", + "default": "" + }, + "x-kubernetes-list-type": "atomic" + }, + "description": { + "description": "Description is a user-facing description of the stepaction that may be used to populate a UI.", + "type": "string" + }, + "env": { + "description": "List of environment variables to set in the container. Cannot be updated.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/v1.EnvVar" + }, + "x-kubernetes-list-type": "atomic", + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge" + }, + "image": { + "description": "Image reference name to run for this StepAction. More info: https://kubernetes.io/docs/concepts/containers/images", + "type": "string" + }, + "params": { + "description": "Params is a list of input parameters required to run the stepAction. Params must be supplied as inputs in Steps unless they declare a defaultvalue.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/v1.ParamSpec" + }, + "x-kubernetes-list-type": "atomic" + }, + "results": { + "description": "Results are values that this StepAction can output", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/v1.StepResult" + }, + "x-kubernetes-list-type": "atomic" + }, + "script": { + "description": "Script is the contents of an executable file to execute.\n\nIf Script is not empty, the Step cannot have an Command and the Args will be passed to the Script.", + "type": "string" + }, + "securityContext": { + "description": "SecurityContext defines the security options the Step should be run with. If set, the fields of SecurityContext override the equivalent fields of PodSecurityContext. More info: https://kubernetes.io/docs/tasks/configure-pod-container/security-context/ The value set in StepAction will take precedence over the value from Task.", + "$ref": "#/definitions/v1.SecurityContext" + }, + "volumeMounts": { + "description": "Volumes to mount into the Step's filesystem. Cannot be updated.", + "type": "array", + "items": { + "default": {}, + "$ref": "#/definitions/v1.VolumeMount" + }, + "x-kubernetes-list-type": "atomic", + "x-kubernetes-patch-merge-key": "mountPath", + "x-kubernetes-patch-strategy": "merge" + }, + "workingDir": { + "description": "Step's working directory. If not specified, the container runtime's default will be used, which might be configured in the container image. Cannot be updated.", + "type": "string" + } + } + }, "v1beta1.StepOutputConfig": { "description": "StepOutputConfig stores configuration for a step output stream.", "type": "object", diff --git a/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go b/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go index 807595a1925..04d3a09ad2e 100644 --- a/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go +++ b/pkg/apis/pipeline/v1beta1/zz_generated.deepcopy.go @@ -1871,6 +1871,125 @@ func (in *Step) DeepCopy() *Step { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StepAction) DeepCopyInto(out *StepAction) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StepAction. +func (in *StepAction) DeepCopy() *StepAction { + if in == nil { + return nil + } + out := new(StepAction) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *StepAction) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StepActionList) DeepCopyInto(out *StepActionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]StepAction, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StepActionList. +func (in *StepActionList) DeepCopy() *StepActionList { + if in == nil { + return nil + } + out := new(StepActionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *StepActionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *StepActionSpec) DeepCopyInto(out *StepActionSpec) { + *out = *in + if in.Command != nil { + in, out := &in.Command, &out.Command + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Args != nil { + in, out := &in.Args, &out.Args + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]corev1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Params != nil { + in, out := &in.Params, &out.Params + *out = make(pipelinev1.ParamSpecs, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Results != nil { + in, out := &in.Results, &out.Results + *out = make([]pipelinev1.StepResult, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.SecurityContext != nil { + in, out := &in.SecurityContext, &out.SecurityContext + *out = new(corev1.SecurityContext) + (*in).DeepCopyInto(*out) + } + if in.VolumeMounts != nil { + in, out := &in.VolumeMounts, &out.VolumeMounts + *out = make([]corev1.VolumeMount, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new StepActionSpec. +func (in *StepActionSpec) DeepCopy() *StepActionSpec { + if in == nil { + return nil + } + out := new(StepActionSpec) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *StepOutputConfig) DeepCopyInto(out *StepOutputConfig) { *out = *in diff --git a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_pipeline_client.go b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_pipeline_client.go index a142026b2ba..326e2fbb252 100644 --- a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_pipeline_client.go +++ b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_pipeline_client.go @@ -44,6 +44,10 @@ func (c *FakeTektonV1beta1) PipelineRuns(namespace string) v1beta1.PipelineRunIn return &FakePipelineRuns{c, namespace} } +func (c *FakeTektonV1beta1) StepActions(namespace string) v1beta1.StepActionInterface { + return &FakeStepActions{c, namespace} +} + func (c *FakeTektonV1beta1) Tasks(namespace string) v1beta1.TaskInterface { return &FakeTasks{c, namespace} } diff --git a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_stepaction.go b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_stepaction.go new file mode 100644 index 00000000000..048c9e56c34 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/fake/fake_stepaction.go @@ -0,0 +1,129 @@ +/* +Copyright 2020 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package fake + +import ( + "context" + + v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + testing "k8s.io/client-go/testing" +) + +// FakeStepActions implements StepActionInterface +type FakeStepActions struct { + Fake *FakeTektonV1beta1 + ns string +} + +var stepactionsResource = v1beta1.SchemeGroupVersion.WithResource("stepactions") + +var stepactionsKind = v1beta1.SchemeGroupVersion.WithKind("StepAction") + +// Get takes name of the stepAction, and returns the corresponding stepAction object, and an error if there is any. +func (c *FakeStepActions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.StepAction, err error) { + obj, err := c.Fake. + Invokes(testing.NewGetAction(stepactionsResource, c.ns, name), &v1beta1.StepAction{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.StepAction), err +} + +// List takes label and field selectors, and returns the list of StepActions that match those selectors. +func (c *FakeStepActions) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.StepActionList, err error) { + obj, err := c.Fake. + Invokes(testing.NewListAction(stepactionsResource, stepactionsKind, c.ns, opts), &v1beta1.StepActionList{}) + + if obj == nil { + return nil, err + } + + label, _, _ := testing.ExtractFromListOptions(opts) + if label == nil { + label = labels.Everything() + } + list := &v1beta1.StepActionList{ListMeta: obj.(*v1beta1.StepActionList).ListMeta} + for _, item := range obj.(*v1beta1.StepActionList).Items { + if label.Matches(labels.Set(item.Labels)) { + list.Items = append(list.Items, item) + } + } + return list, err +} + +// Watch returns a watch.Interface that watches the requested stepActions. +func (c *FakeStepActions) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + return c.Fake. + InvokesWatch(testing.NewWatchAction(stepactionsResource, c.ns, opts)) + +} + +// Create takes the representation of a stepAction and creates it. Returns the server's representation of the stepAction, and an error, if there is any. +func (c *FakeStepActions) Create(ctx context.Context, stepAction *v1beta1.StepAction, opts v1.CreateOptions) (result *v1beta1.StepAction, err error) { + obj, err := c.Fake. + Invokes(testing.NewCreateAction(stepactionsResource, c.ns, stepAction), &v1beta1.StepAction{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.StepAction), err +} + +// Update takes the representation of a stepAction and updates it. Returns the server's representation of the stepAction, and an error, if there is any. +func (c *FakeStepActions) Update(ctx context.Context, stepAction *v1beta1.StepAction, opts v1.UpdateOptions) (result *v1beta1.StepAction, err error) { + obj, err := c.Fake. + Invokes(testing.NewUpdateAction(stepactionsResource, c.ns, stepAction), &v1beta1.StepAction{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.StepAction), err +} + +// Delete takes name of the stepAction and deletes it. Returns an error if one occurs. +func (c *FakeStepActions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + _, err := c.Fake. + Invokes(testing.NewDeleteActionWithOptions(stepactionsResource, c.ns, name, opts), &v1beta1.StepAction{}) + + return err +} + +// DeleteCollection deletes a collection of objects. +func (c *FakeStepActions) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + action := testing.NewDeleteCollectionAction(stepactionsResource, c.ns, listOpts) + + _, err := c.Fake.Invokes(action, &v1beta1.StepActionList{}) + return err +} + +// Patch applies the patch and returns the patched stepAction. +func (c *FakeStepActions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.StepAction, err error) { + obj, err := c.Fake. + Invokes(testing.NewPatchSubresourceAction(stepactionsResource, c.ns, name, pt, data, subresources...), &v1beta1.StepAction{}) + + if obj == nil { + return nil, err + } + return obj.(*v1beta1.StepAction), err +} diff --git a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/generated_expansion.go b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/generated_expansion.go index b9f3554be3e..87f277c5c7a 100644 --- a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/generated_expansion.go +++ b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/generated_expansion.go @@ -26,6 +26,8 @@ type PipelineExpansion interface{} type PipelineRunExpansion interface{} +type StepActionExpansion interface{} + type TaskExpansion interface{} type TaskRunExpansion interface{} diff --git a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/pipeline_client.go b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/pipeline_client.go index 0974d31771a..fcd65e7ce35 100644 --- a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/pipeline_client.go +++ b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/pipeline_client.go @@ -32,6 +32,7 @@ type TektonV1beta1Interface interface { CustomRunsGetter PipelinesGetter PipelineRunsGetter + StepActionsGetter TasksGetter TaskRunsGetter } @@ -57,6 +58,10 @@ func (c *TektonV1beta1Client) PipelineRuns(namespace string) PipelineRunInterfac return newPipelineRuns(c, namespace) } +func (c *TektonV1beta1Client) StepActions(namespace string) StepActionInterface { + return newStepActions(c, namespace) +} + func (c *TektonV1beta1Client) Tasks(namespace string) TaskInterface { return newTasks(c, namespace) } diff --git a/pkg/client/clientset/versioned/typed/pipeline/v1beta1/stepaction.go b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/stepaction.go new file mode 100644 index 00000000000..388f0629540 --- /dev/null +++ b/pkg/client/clientset/versioned/typed/pipeline/v1beta1/stepaction.go @@ -0,0 +1,178 @@ +/* +Copyright 2020 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by client-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + "time" + + v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + scheme "github.com/tektoncd/pipeline/pkg/client/clientset/versioned/scheme" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + rest "k8s.io/client-go/rest" +) + +// StepActionsGetter has a method to return a StepActionInterface. +// A group's client should implement this interface. +type StepActionsGetter interface { + StepActions(namespace string) StepActionInterface +} + +// StepActionInterface has methods to work with StepAction resources. +type StepActionInterface interface { + Create(ctx context.Context, stepAction *v1beta1.StepAction, opts v1.CreateOptions) (*v1beta1.StepAction, error) + Update(ctx context.Context, stepAction *v1beta1.StepAction, opts v1.UpdateOptions) (*v1beta1.StepAction, error) + Delete(ctx context.Context, name string, opts v1.DeleteOptions) error + DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error + Get(ctx context.Context, name string, opts v1.GetOptions) (*v1beta1.StepAction, error) + List(ctx context.Context, opts v1.ListOptions) (*v1beta1.StepActionList, error) + Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) + Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.StepAction, err error) + StepActionExpansion +} + +// stepActions implements StepActionInterface +type stepActions struct { + client rest.Interface + ns string +} + +// newStepActions returns a StepActions +func newStepActions(c *TektonV1beta1Client, namespace string) *stepActions { + return &stepActions{ + client: c.RESTClient(), + ns: namespace, + } +} + +// Get takes name of the stepAction, and returns the corresponding stepAction object, and an error if there is any. +func (c *stepActions) Get(ctx context.Context, name string, options v1.GetOptions) (result *v1beta1.StepAction, err error) { + result = &v1beta1.StepAction{} + err = c.client.Get(). + Namespace(c.ns). + Resource("stepactions"). + Name(name). + VersionedParams(&options, scheme.ParameterCodec). + Do(ctx). + Into(result) + return +} + +// List takes label and field selectors, and returns the list of StepActions that match those selectors. +func (c *stepActions) List(ctx context.Context, opts v1.ListOptions) (result *v1beta1.StepActionList, err error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + result = &v1beta1.StepActionList{} + err = c.client.Get(). + Namespace(c.ns). + Resource("stepactions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Do(ctx). + Into(result) + return +} + +// Watch returns a watch.Interface that watches the requested stepActions. +func (c *stepActions) Watch(ctx context.Context, opts v1.ListOptions) (watch.Interface, error) { + var timeout time.Duration + if opts.TimeoutSeconds != nil { + timeout = time.Duration(*opts.TimeoutSeconds) * time.Second + } + opts.Watch = true + return c.client.Get(). + Namespace(c.ns). + Resource("stepactions"). + VersionedParams(&opts, scheme.ParameterCodec). + Timeout(timeout). + Watch(ctx) +} + +// Create takes the representation of a stepAction and creates it. Returns the server's representation of the stepAction, and an error, if there is any. +func (c *stepActions) Create(ctx context.Context, stepAction *v1beta1.StepAction, opts v1.CreateOptions) (result *v1beta1.StepAction, err error) { + result = &v1beta1.StepAction{} + err = c.client.Post(). + Namespace(c.ns). + Resource("stepactions"). + VersionedParams(&opts, scheme.ParameterCodec). + Body(stepAction). + Do(ctx). + Into(result) + return +} + +// Update takes the representation of a stepAction and updates it. Returns the server's representation of the stepAction, and an error, if there is any. +func (c *stepActions) Update(ctx context.Context, stepAction *v1beta1.StepAction, opts v1.UpdateOptions) (result *v1beta1.StepAction, err error) { + result = &v1beta1.StepAction{} + err = c.client.Put(). + Namespace(c.ns). + Resource("stepactions"). + Name(stepAction.Name). + VersionedParams(&opts, scheme.ParameterCodec). + Body(stepAction). + Do(ctx). + Into(result) + return +} + +// Delete takes name of the stepAction and deletes it. Returns an error if one occurs. +func (c *stepActions) Delete(ctx context.Context, name string, opts v1.DeleteOptions) error { + return c.client.Delete(). + Namespace(c.ns). + Resource("stepactions"). + Name(name). + Body(&opts). + Do(ctx). + Error() +} + +// DeleteCollection deletes a collection of objects. +func (c *stepActions) DeleteCollection(ctx context.Context, opts v1.DeleteOptions, listOpts v1.ListOptions) error { + var timeout time.Duration + if listOpts.TimeoutSeconds != nil { + timeout = time.Duration(*listOpts.TimeoutSeconds) * time.Second + } + return c.client.Delete(). + Namespace(c.ns). + Resource("stepactions"). + VersionedParams(&listOpts, scheme.ParameterCodec). + Timeout(timeout). + Body(&opts). + Do(ctx). + Error() +} + +// Patch applies the patch and returns the patched stepAction. +func (c *stepActions) Patch(ctx context.Context, name string, pt types.PatchType, data []byte, opts v1.PatchOptions, subresources ...string) (result *v1beta1.StepAction, err error) { + result = &v1beta1.StepAction{} + err = c.client.Patch(pt). + Namespace(c.ns). + Resource("stepactions"). + Name(name). + SubResource(subresources...). + VersionedParams(&opts, scheme.ParameterCodec). + Body(data). + Do(ctx). + Into(result) + return +} diff --git a/pkg/client/informers/externalversions/generic.go b/pkg/client/informers/externalversions/generic.go index cec37e05376..fe44a25ab11 100644 --- a/pkg/client/informers/externalversions/generic.go +++ b/pkg/client/informers/externalversions/generic.go @@ -81,6 +81,8 @@ func (f *sharedInformerFactory) ForResource(resource schema.GroupVersionResource return &genericInformer{resource: resource.GroupResource(), informer: f.Tekton().V1beta1().Pipelines().Informer()}, nil case v1beta1.SchemeGroupVersion.WithResource("pipelineruns"): return &genericInformer{resource: resource.GroupResource(), informer: f.Tekton().V1beta1().PipelineRuns().Informer()}, nil + case v1beta1.SchemeGroupVersion.WithResource("stepactions"): + return &genericInformer{resource: resource.GroupResource(), informer: f.Tekton().V1beta1().StepActions().Informer()}, nil case v1beta1.SchemeGroupVersion.WithResource("tasks"): return &genericInformer{resource: resource.GroupResource(), informer: f.Tekton().V1beta1().Tasks().Informer()}, nil case v1beta1.SchemeGroupVersion.WithResource("taskruns"): diff --git a/pkg/client/informers/externalversions/pipeline/v1beta1/interface.go b/pkg/client/informers/externalversions/pipeline/v1beta1/interface.go index 307843a8014..2821b942ca9 100644 --- a/pkg/client/informers/externalversions/pipeline/v1beta1/interface.go +++ b/pkg/client/informers/externalversions/pipeline/v1beta1/interface.go @@ -32,6 +32,8 @@ type Interface interface { Pipelines() PipelineInformer // PipelineRuns returns a PipelineRunInformer. PipelineRuns() PipelineRunInformer + // StepActions returns a StepActionInformer. + StepActions() StepActionInformer // Tasks returns a TaskInformer. Tasks() TaskInformer // TaskRuns returns a TaskRunInformer. @@ -69,6 +71,11 @@ func (v *version) PipelineRuns() PipelineRunInformer { return &pipelineRunInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} } +// StepActions returns a StepActionInformer. +func (v *version) StepActions() StepActionInformer { + return &stepActionInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} +} + // Tasks returns a TaskInformer. func (v *version) Tasks() TaskInformer { return &taskInformer{factory: v.factory, namespace: v.namespace, tweakListOptions: v.tweakListOptions} diff --git a/pkg/client/informers/externalversions/pipeline/v1beta1/stepaction.go b/pkg/client/informers/externalversions/pipeline/v1beta1/stepaction.go new file mode 100644 index 00000000000..4ec8578199e --- /dev/null +++ b/pkg/client/informers/externalversions/pipeline/v1beta1/stepaction.go @@ -0,0 +1,90 @@ +/* +Copyright 2020 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by informer-gen. DO NOT EDIT. + +package v1beta1 + +import ( + "context" + time "time" + + pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + versioned "github.com/tektoncd/pipeline/pkg/client/clientset/versioned" + internalinterfaces "github.com/tektoncd/pipeline/pkg/client/informers/externalversions/internalinterfaces" + v1beta1 "github.com/tektoncd/pipeline/pkg/client/listers/pipeline/v1beta1" + v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + runtime "k8s.io/apimachinery/pkg/runtime" + watch "k8s.io/apimachinery/pkg/watch" + cache "k8s.io/client-go/tools/cache" +) + +// StepActionInformer provides access to a shared informer and lister for +// StepActions. +type StepActionInformer interface { + Informer() cache.SharedIndexInformer + Lister() v1beta1.StepActionLister +} + +type stepActionInformer struct { + factory internalinterfaces.SharedInformerFactory + tweakListOptions internalinterfaces.TweakListOptionsFunc + namespace string +} + +// NewStepActionInformer constructs a new informer for StepAction type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewStepActionInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers) cache.SharedIndexInformer { + return NewFilteredStepActionInformer(client, namespace, resyncPeriod, indexers, nil) +} + +// NewFilteredStepActionInformer constructs a new informer for StepAction type. +// Always prefer using an informer factory to get a shared informer instead of getting an independent +// one. This reduces memory footprint and number of connections to the server. +func NewFilteredStepActionInformer(client versioned.Interface, namespace string, resyncPeriod time.Duration, indexers cache.Indexers, tweakListOptions internalinterfaces.TweakListOptionsFunc) cache.SharedIndexInformer { + return cache.NewSharedIndexInformer( + &cache.ListWatch{ + ListFunc: func(options v1.ListOptions) (runtime.Object, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.TektonV1beta1().StepActions(namespace).List(context.TODO(), options) + }, + WatchFunc: func(options v1.ListOptions) (watch.Interface, error) { + if tweakListOptions != nil { + tweakListOptions(&options) + } + return client.TektonV1beta1().StepActions(namespace).Watch(context.TODO(), options) + }, + }, + &pipelinev1beta1.StepAction{}, + resyncPeriod, + indexers, + ) +} + +func (f *stepActionInformer) defaultInformer(client versioned.Interface, resyncPeriod time.Duration) cache.SharedIndexInformer { + return NewFilteredStepActionInformer(client, f.namespace, resyncPeriod, cache.Indexers{cache.NamespaceIndex: cache.MetaNamespaceIndexFunc}, f.tweakListOptions) +} + +func (f *stepActionInformer) Informer() cache.SharedIndexInformer { + return f.factory.InformerFor(&pipelinev1beta1.StepAction{}, f.defaultInformer) +} + +func (f *stepActionInformer) Lister() v1beta1.StepActionLister { + return v1beta1.NewStepActionLister(f.Informer().GetIndexer()) +} diff --git a/pkg/client/injection/informers/pipeline/v1beta1/stepaction/fake/fake.go b/pkg/client/injection/informers/pipeline/v1beta1/stepaction/fake/fake.go new file mode 100644 index 00000000000..7372bf60da5 --- /dev/null +++ b/pkg/client/injection/informers/pipeline/v1beta1/stepaction/fake/fake.go @@ -0,0 +1,40 @@ +/* +Copyright 2020 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + context "context" + + fake "github.com/tektoncd/pipeline/pkg/client/injection/informers/factory/fake" + stepaction "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1beta1/stepaction" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" +) + +var Get = stepaction.Get + +func init() { + injection.Fake.RegisterInformer(withInformer) +} + +func withInformer(ctx context.Context) (context.Context, controller.Informer) { + f := fake.Get(ctx) + inf := f.Tekton().V1beta1().StepActions() + return context.WithValue(ctx, stepaction.Key{}, inf), inf.Informer() +} diff --git a/pkg/client/injection/informers/pipeline/v1beta1/stepaction/filtered/fake/fake.go b/pkg/client/injection/informers/pipeline/v1beta1/stepaction/filtered/fake/fake.go new file mode 100644 index 00000000000..209d758a1de --- /dev/null +++ b/pkg/client/injection/informers/pipeline/v1beta1/stepaction/filtered/fake/fake.go @@ -0,0 +1,52 @@ +/* +Copyright 2020 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package fake + +import ( + context "context" + + factoryfiltered "github.com/tektoncd/pipeline/pkg/client/injection/informers/factory/filtered" + filtered "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1beta1/stepaction/filtered" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + logging "knative.dev/pkg/logging" +) + +var Get = filtered.Get + +func init() { + injection.Fake.RegisterFilteredInformers(withInformer) +} + +func withInformer(ctx context.Context) (context.Context, []controller.Informer) { + untyped := ctx.Value(factoryfiltered.LabelKey{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch labelkey from context.") + } + labelSelectors := untyped.([]string) + infs := []controller.Informer{} + for _, selector := range labelSelectors { + f := factoryfiltered.Get(ctx, selector) + inf := f.Tekton().V1beta1().StepActions() + ctx = context.WithValue(ctx, filtered.Key{Selector: selector}, inf) + infs = append(infs, inf.Informer()) + } + return ctx, infs +} diff --git a/pkg/client/injection/informers/pipeline/v1beta1/stepaction/filtered/stepaction.go b/pkg/client/injection/informers/pipeline/v1beta1/stepaction/filtered/stepaction.go new file mode 100644 index 00000000000..efc517d9ded --- /dev/null +++ b/pkg/client/injection/informers/pipeline/v1beta1/stepaction/filtered/stepaction.go @@ -0,0 +1,65 @@ +/* +Copyright 2020 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package filtered + +import ( + context "context" + + v1beta1 "github.com/tektoncd/pipeline/pkg/client/informers/externalversions/pipeline/v1beta1" + filtered "github.com/tektoncd/pipeline/pkg/client/injection/informers/factory/filtered" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterFilteredInformers(withInformer) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct { + Selector string +} + +func withInformer(ctx context.Context) (context.Context, []controller.Informer) { + untyped := ctx.Value(filtered.LabelKey{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch labelkey from context.") + } + labelSelectors := untyped.([]string) + infs := []controller.Informer{} + for _, selector := range labelSelectors { + f := filtered.Get(ctx, selector) + inf := f.Tekton().V1beta1().StepActions() + ctx = context.WithValue(ctx, Key{Selector: selector}, inf) + infs = append(infs, inf.Informer()) + } + return ctx, infs +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context, selector string) v1beta1.StepActionInformer { + untyped := ctx.Value(Key{Selector: selector}) + if untyped == nil { + logging.FromContext(ctx).Panicf( + "Unable to fetch github.com/tektoncd/pipeline/pkg/client/informers/externalversions/pipeline/v1beta1.StepActionInformer with selector %s from context.", selector) + } + return untyped.(v1beta1.StepActionInformer) +} diff --git a/pkg/client/injection/informers/pipeline/v1beta1/stepaction/stepaction.go b/pkg/client/injection/informers/pipeline/v1beta1/stepaction/stepaction.go new file mode 100644 index 00000000000..ffb873d1965 --- /dev/null +++ b/pkg/client/injection/informers/pipeline/v1beta1/stepaction/stepaction.go @@ -0,0 +1,52 @@ +/* +Copyright 2020 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package stepaction + +import ( + context "context" + + v1beta1 "github.com/tektoncd/pipeline/pkg/client/informers/externalversions/pipeline/v1beta1" + factory "github.com/tektoncd/pipeline/pkg/client/injection/informers/factory" + controller "knative.dev/pkg/controller" + injection "knative.dev/pkg/injection" + logging "knative.dev/pkg/logging" +) + +func init() { + injection.Default.RegisterInformer(withInformer) +} + +// Key is used for associating the Informer inside the context.Context. +type Key struct{} + +func withInformer(ctx context.Context) (context.Context, controller.Informer) { + f := factory.Get(ctx) + inf := f.Tekton().V1beta1().StepActions() + return context.WithValue(ctx, Key{}, inf), inf.Informer() +} + +// Get extracts the typed informer from the context. +func Get(ctx context.Context) v1beta1.StepActionInformer { + untyped := ctx.Value(Key{}) + if untyped == nil { + logging.FromContext(ctx).Panic( + "Unable to fetch github.com/tektoncd/pipeline/pkg/client/informers/externalversions/pipeline/v1beta1.StepActionInformer from context.") + } + return untyped.(v1beta1.StepActionInformer) +} diff --git a/pkg/client/injection/reconciler/pipeline/v1beta1/stepaction/controller.go b/pkg/client/injection/reconciler/pipeline/v1beta1/stepaction/controller.go new file mode 100644 index 00000000000..b5caba0fdb6 --- /dev/null +++ b/pkg/client/injection/reconciler/pipeline/v1beta1/stepaction/controller.go @@ -0,0 +1,167 @@ +/* +Copyright 2020 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package stepaction + +import ( + context "context" + fmt "fmt" + reflect "reflect" + strings "strings" + + versionedscheme "github.com/tektoncd/pipeline/pkg/client/clientset/versioned/scheme" + client "github.com/tektoncd/pipeline/pkg/client/injection/client" + stepaction "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1beta1/stepaction" + zap "go.uber.org/zap" + corev1 "k8s.io/api/core/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + watch "k8s.io/apimachinery/pkg/watch" + scheme "k8s.io/client-go/kubernetes/scheme" + v1 "k8s.io/client-go/kubernetes/typed/core/v1" + record "k8s.io/client-go/tools/record" + kubeclient "knative.dev/pkg/client/injection/kube/client" + controller "knative.dev/pkg/controller" + logging "knative.dev/pkg/logging" + logkey "knative.dev/pkg/logging/logkey" + reconciler "knative.dev/pkg/reconciler" +) + +const ( + defaultControllerAgentName = "stepaction-controller" + defaultFinalizerName = "stepactions.tekton.dev" +) + +// NewImpl returns a controller.Impl that handles queuing and feeding work from +// the queue through an implementation of controller.Reconciler, delegating to +// the provided Interface and optional Finalizer methods. OptionsFn is used to return +// controller.ControllerOptions to be used by the internal reconciler. +func NewImpl(ctx context.Context, r Interface, optionsFns ...controller.OptionsFn) *controller.Impl { + logger := logging.FromContext(ctx) + + // Check the options function input. It should be 0 or 1. + if len(optionsFns) > 1 { + logger.Fatal("Up to one options function is supported, found: ", len(optionsFns)) + } + + stepactionInformer := stepaction.Get(ctx) + + lister := stepactionInformer.Lister() + + var promoteFilterFunc func(obj interface{}) bool + var promoteFunc = func(bkt reconciler.Bucket) {} + + rec := &reconcilerImpl{ + LeaderAwareFuncs: reconciler.LeaderAwareFuncs{ + PromoteFunc: func(bkt reconciler.Bucket, enq func(reconciler.Bucket, types.NamespacedName)) error { + + // Signal promotion event + promoteFunc(bkt) + + all, err := lister.List(labels.Everything()) + if err != nil { + return err + } + for _, elt := range all { + if promoteFilterFunc != nil { + if ok := promoteFilterFunc(elt); !ok { + continue + } + } + enq(bkt, types.NamespacedName{ + Namespace: elt.GetNamespace(), + Name: elt.GetName(), + }) + } + return nil + }, + }, + Client: client.Get(ctx), + Lister: lister, + reconciler: r, + finalizerName: defaultFinalizerName, + } + + ctrType := reflect.TypeOf(r).Elem() + ctrTypeName := fmt.Sprintf("%s.%s", ctrType.PkgPath(), ctrType.Name()) + ctrTypeName = strings.ReplaceAll(ctrTypeName, "/", ".") + + logger = logger.With( + zap.String(logkey.ControllerType, ctrTypeName), + zap.String(logkey.Kind, "tekton.dev.StepAction"), + ) + + impl := controller.NewContext(ctx, rec, controller.ControllerOptions{WorkQueueName: ctrTypeName, Logger: logger}) + agentName := defaultControllerAgentName + + // Pass impl to the options. Save any optional results. + for _, fn := range optionsFns { + opts := fn(impl) + if opts.ConfigStore != nil { + rec.configStore = opts.ConfigStore + } + if opts.FinalizerName != "" { + rec.finalizerName = opts.FinalizerName + } + if opts.AgentName != "" { + agentName = opts.AgentName + } + if opts.DemoteFunc != nil { + rec.DemoteFunc = opts.DemoteFunc + } + if opts.PromoteFilterFunc != nil { + promoteFilterFunc = opts.PromoteFilterFunc + } + if opts.PromoteFunc != nil { + promoteFunc = opts.PromoteFunc + } + } + + rec.Recorder = createRecorder(ctx, agentName) + + return impl +} + +func createRecorder(ctx context.Context, agentName string) record.EventRecorder { + logger := logging.FromContext(ctx) + + recorder := controller.GetEventRecorder(ctx) + if recorder == nil { + // Create event broadcaster + logger.Debug("Creating event broadcaster") + eventBroadcaster := record.NewBroadcaster() + watches := []watch.Interface{ + eventBroadcaster.StartLogging(logger.Named("event-broadcaster").Infof), + eventBroadcaster.StartRecordingToSink( + &v1.EventSinkImpl{Interface: kubeclient.Get(ctx).CoreV1().Events("")}), + } + recorder = eventBroadcaster.NewRecorder(scheme.Scheme, corev1.EventSource{Component: agentName}) + go func() { + <-ctx.Done() + for _, w := range watches { + w.Stop() + } + }() + } + + return recorder +} + +func init() { + versionedscheme.AddToScheme(scheme.Scheme) +} diff --git a/pkg/client/injection/reconciler/pipeline/v1beta1/stepaction/reconciler.go b/pkg/client/injection/reconciler/pipeline/v1beta1/stepaction/reconciler.go new file mode 100644 index 00000000000..db1600a9be0 --- /dev/null +++ b/pkg/client/injection/reconciler/pipeline/v1beta1/stepaction/reconciler.go @@ -0,0 +1,365 @@ +/* +Copyright 2020 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package stepaction + +import ( + context "context" + json "encoding/json" + fmt "fmt" + + v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + versioned "github.com/tektoncd/pipeline/pkg/client/clientset/versioned" + pipelinev1beta1 "github.com/tektoncd/pipeline/pkg/client/listers/pipeline/v1beta1" + zap "go.uber.org/zap" + v1 "k8s.io/api/core/v1" + errors "k8s.io/apimachinery/pkg/api/errors" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + labels "k8s.io/apimachinery/pkg/labels" + types "k8s.io/apimachinery/pkg/types" + sets "k8s.io/apimachinery/pkg/util/sets" + record "k8s.io/client-go/tools/record" + controller "knative.dev/pkg/controller" + logging "knative.dev/pkg/logging" + reconciler "knative.dev/pkg/reconciler" +) + +// Interface defines the strongly typed interfaces to be implemented by a +// controller reconciling v1beta1.StepAction. +type Interface interface { + // ReconcileKind implements custom logic to reconcile v1beta1.StepAction. Any changes + // to the objects .Status or .Finalizers will be propagated to the stored + // object. It is recommended that implementors do not call any update calls + // for the Kind inside of ReconcileKind, it is the responsibility of the calling + // controller to propagate those properties. The resource passed to ReconcileKind + // will always have an empty deletion timestamp. + ReconcileKind(ctx context.Context, o *v1beta1.StepAction) reconciler.Event +} + +// Finalizer defines the strongly typed interfaces to be implemented by a +// controller finalizing v1beta1.StepAction. +type Finalizer interface { + // FinalizeKind implements custom logic to finalize v1beta1.StepAction. Any changes + // to the objects .Status or .Finalizers will be ignored. Returning a nil or + // Normal type reconciler.Event will allow the finalizer to be deleted on + // the resource. The resource passed to FinalizeKind will always have a set + // deletion timestamp. + FinalizeKind(ctx context.Context, o *v1beta1.StepAction) reconciler.Event +} + +// ReadOnlyInterface defines the strongly typed interfaces to be implemented by a +// controller reconciling v1beta1.StepAction if they want to process resources for which +// they are not the leader. +type ReadOnlyInterface interface { + // ObserveKind implements logic to observe v1beta1.StepAction. + // This method should not write to the API. + ObserveKind(ctx context.Context, o *v1beta1.StepAction) reconciler.Event +} + +type doReconcile func(ctx context.Context, o *v1beta1.StepAction) reconciler.Event + +// reconcilerImpl implements controller.Reconciler for v1beta1.StepAction resources. +type reconcilerImpl struct { + // LeaderAwareFuncs is inlined to help us implement reconciler.LeaderAware. + reconciler.LeaderAwareFuncs + + // Client is used to write back status updates. + Client versioned.Interface + + // Listers index properties about resources. + Lister pipelinev1beta1.StepActionLister + + // Recorder is an event recorder for recording Event resources to the + // Kubernetes API. + Recorder record.EventRecorder + + // configStore allows for decorating a context with config maps. + // +optional + configStore reconciler.ConfigStore + + // reconciler is the implementation of the business logic of the resource. + reconciler Interface + + // finalizerName is the name of the finalizer to reconcile. + finalizerName string +} + +// Check that our Reconciler implements controller.Reconciler. +var _ controller.Reconciler = (*reconcilerImpl)(nil) + +// Check that our generated Reconciler is always LeaderAware. +var _ reconciler.LeaderAware = (*reconcilerImpl)(nil) + +func NewReconciler(ctx context.Context, logger *zap.SugaredLogger, client versioned.Interface, lister pipelinev1beta1.StepActionLister, recorder record.EventRecorder, r Interface, options ...controller.Options) controller.Reconciler { + // Check the options function input. It should be 0 or 1. + if len(options) > 1 { + logger.Fatal("Up to one options struct is supported, found: ", len(options)) + } + + // Fail fast when users inadvertently implement the other LeaderAware interface. + // For the typed reconcilers, Promote shouldn't take any arguments. + if _, ok := r.(reconciler.LeaderAware); ok { + logger.Fatalf("%T implements the incorrect LeaderAware interface. Promote() should not take an argument as genreconciler handles the enqueuing automatically.", r) + } + + rec := &reconcilerImpl{ + LeaderAwareFuncs: reconciler.LeaderAwareFuncs{ + PromoteFunc: func(bkt reconciler.Bucket, enq func(reconciler.Bucket, types.NamespacedName)) error { + all, err := lister.List(labels.Everything()) + if err != nil { + return err + } + for _, elt := range all { + // TODO: Consider letting users specify a filter in options. + enq(bkt, types.NamespacedName{ + Namespace: elt.GetNamespace(), + Name: elt.GetName(), + }) + } + return nil + }, + }, + Client: client, + Lister: lister, + Recorder: recorder, + reconciler: r, + finalizerName: defaultFinalizerName, + } + + for _, opts := range options { + if opts.ConfigStore != nil { + rec.configStore = opts.ConfigStore + } + if opts.FinalizerName != "" { + rec.finalizerName = opts.FinalizerName + } + if opts.DemoteFunc != nil { + rec.DemoteFunc = opts.DemoteFunc + } + } + + return rec +} + +// Reconcile implements controller.Reconciler +func (r *reconcilerImpl) Reconcile(ctx context.Context, key string) error { + logger := logging.FromContext(ctx) + + // Initialize the reconciler state. This will convert the namespace/name + // string into a distinct namespace and name, determine if this instance of + // the reconciler is the leader, and any additional interfaces implemented + // by the reconciler. Returns an error is the resource key is invalid. + s, err := newState(key, r) + if err != nil { + logger.Error("Invalid resource key: ", key) + return nil + } + + // If we are not the leader, and we don't implement either ReadOnly + // observer interfaces, then take a fast-path out. + if s.isNotLeaderNorObserver() { + return controller.NewSkipKey(key) + } + + // If configStore is set, attach the frozen configuration to the context. + if r.configStore != nil { + ctx = r.configStore.ToContext(ctx) + } + + // Add the recorder to context. + ctx = controller.WithEventRecorder(ctx, r.Recorder) + + // Get the resource with this namespace/name. + + getter := r.Lister.StepActions(s.namespace) + + original, err := getter.Get(s.name) + + if errors.IsNotFound(err) { + // The resource may no longer exist, in which case we stop processing and call + // the ObserveDeletion handler if appropriate. + logger.Debugf("Resource %q no longer exists", key) + if del, ok := r.reconciler.(reconciler.OnDeletionInterface); ok { + return del.ObserveDeletion(ctx, types.NamespacedName{ + Namespace: s.namespace, + Name: s.name, + }) + } + return nil + } else if err != nil { + return err + } + + // Don't modify the informers copy. + resource := original.DeepCopy() + + var reconcileEvent reconciler.Event + + name, do := s.reconcileMethodFor(resource) + // Append the target method to the logger. + logger = logger.With(zap.String("targetMethod", name)) + switch name { + case reconciler.DoReconcileKind: + // Set and update the finalizer on resource if r.reconciler + // implements Finalizer. + if resource, err = r.setFinalizerIfFinalizer(ctx, resource); err != nil { + return fmt.Errorf("failed to set finalizers: %w", err) + } + + // Reconcile this copy of the resource and then write back any status + // updates regardless of whether the reconciliation errored out. + reconcileEvent = do(ctx, resource) + + case reconciler.DoFinalizeKind: + // For finalizing reconcilers, if this resource being marked for deletion + // and reconciled cleanly (nil or normal event), remove the finalizer. + reconcileEvent = do(ctx, resource) + + if resource, err = r.clearFinalizer(ctx, resource, reconcileEvent); err != nil { + return fmt.Errorf("failed to clear finalizers: %w", err) + } + + case reconciler.DoObserveKind: + // Observe any changes to this resource, since we are not the leader. + reconcileEvent = do(ctx, resource) + + } + + // Report the reconciler event, if any. + if reconcileEvent != nil { + var event *reconciler.ReconcilerEvent + if reconciler.EventAs(reconcileEvent, &event) { + logger.Infow("Returned an event", zap.Any("event", reconcileEvent)) + r.Recorder.Event(resource, event.EventType, event.Reason, event.Error()) + + // the event was wrapped inside an error, consider the reconciliation as failed + if _, isEvent := reconcileEvent.(*reconciler.ReconcilerEvent); !isEvent { + return reconcileEvent + } + return nil + } + + if controller.IsSkipKey(reconcileEvent) { + // This is a wrapped error, don't emit an event. + } else if ok, _ := controller.IsRequeueKey(reconcileEvent); ok { + // This is a wrapped error, don't emit an event. + } else { + logger.Errorw("Returned an error", zap.Error(reconcileEvent)) + r.Recorder.Event(resource, v1.EventTypeWarning, "InternalError", reconcileEvent.Error()) + } + return reconcileEvent + } + + return nil +} + +// updateFinalizersFiltered will update the Finalizers of the resource. +// TODO: this method could be generic and sync all finalizers. For now it only +// updates defaultFinalizerName or its override. +func (r *reconcilerImpl) updateFinalizersFiltered(ctx context.Context, resource *v1beta1.StepAction, desiredFinalizers sets.Set[string]) (*v1beta1.StepAction, error) { + // Don't modify the informers copy. + existing := resource.DeepCopy() + + var finalizers []string + + // If there's nothing to update, just return. + existingFinalizers := sets.New[string](existing.Finalizers...) + + if desiredFinalizers.Has(r.finalizerName) { + if existingFinalizers.Has(r.finalizerName) { + // Nothing to do. + return resource, nil + } + // Add the finalizer. + finalizers = append(existing.Finalizers, r.finalizerName) + } else { + if !existingFinalizers.Has(r.finalizerName) { + // Nothing to do. + return resource, nil + } + // Remove the finalizer. + existingFinalizers.Delete(r.finalizerName) + finalizers = sets.List(existingFinalizers) + } + + mergePatch := map[string]interface{}{ + "metadata": map[string]interface{}{ + "finalizers": finalizers, + "resourceVersion": existing.ResourceVersion, + }, + } + + patch, err := json.Marshal(mergePatch) + if err != nil { + return resource, err + } + + patcher := r.Client.TektonV1beta1().StepActions(resource.Namespace) + + resourceName := resource.Name + updated, err := patcher.Patch(ctx, resourceName, types.MergePatchType, patch, metav1.PatchOptions{}) + if err != nil { + r.Recorder.Eventf(existing, v1.EventTypeWarning, "FinalizerUpdateFailed", + "Failed to update finalizers for %q: %v", resourceName, err) + } else { + r.Recorder.Eventf(updated, v1.EventTypeNormal, "FinalizerUpdate", + "Updated %q finalizers", resource.GetName()) + } + return updated, err +} + +func (r *reconcilerImpl) setFinalizerIfFinalizer(ctx context.Context, resource *v1beta1.StepAction) (*v1beta1.StepAction, error) { + if _, ok := r.reconciler.(Finalizer); !ok { + return resource, nil + } + + finalizers := sets.New[string](resource.Finalizers...) + + // If this resource is not being deleted, mark the finalizer. + if resource.GetDeletionTimestamp().IsZero() { + finalizers.Insert(r.finalizerName) + } + + // Synchronize the finalizers filtered by r.finalizerName. + return r.updateFinalizersFiltered(ctx, resource, finalizers) +} + +func (r *reconcilerImpl) clearFinalizer(ctx context.Context, resource *v1beta1.StepAction, reconcileEvent reconciler.Event) (*v1beta1.StepAction, error) { + if _, ok := r.reconciler.(Finalizer); !ok { + return resource, nil + } + if resource.GetDeletionTimestamp().IsZero() { + return resource, nil + } + + finalizers := sets.New[string](resource.Finalizers...) + + if reconcileEvent != nil { + var event *reconciler.ReconcilerEvent + if reconciler.EventAs(reconcileEvent, &event) { + if event.EventType == v1.EventTypeNormal { + finalizers.Delete(r.finalizerName) + } + } + } else { + finalizers.Delete(r.finalizerName) + } + + // Synchronize the finalizers filtered by r.finalizerName. + return r.updateFinalizersFiltered(ctx, resource, finalizers) +} diff --git a/pkg/client/injection/reconciler/pipeline/v1beta1/stepaction/state.go b/pkg/client/injection/reconciler/pipeline/v1beta1/stepaction/state.go new file mode 100644 index 00000000000..fa6e4b914f8 --- /dev/null +++ b/pkg/client/injection/reconciler/pipeline/v1beta1/stepaction/state.go @@ -0,0 +1,97 @@ +/* +Copyright 2020 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by injection-gen. DO NOT EDIT. + +package stepaction + +import ( + fmt "fmt" + + v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + types "k8s.io/apimachinery/pkg/types" + cache "k8s.io/client-go/tools/cache" + reconciler "knative.dev/pkg/reconciler" +) + +// state is used to track the state of a reconciler in a single run. +type state struct { + // key is the original reconciliation key from the queue. + key string + // namespace is the namespace split from the reconciliation key. + namespace string + // name is the name split from the reconciliation key. + name string + // reconciler is the reconciler. + reconciler Interface + // roi is the read only interface cast of the reconciler. + roi ReadOnlyInterface + // isROI (Read Only Interface) the reconciler only observes reconciliation. + isROI bool + // isLeader the instance of the reconciler is the elected leader. + isLeader bool +} + +func newState(key string, r *reconcilerImpl) (*state, error) { + // Convert the namespace/name string into a distinct namespace and name. + namespace, name, err := cache.SplitMetaNamespaceKey(key) + if err != nil { + return nil, fmt.Errorf("invalid resource key: %s", key) + } + + roi, isROI := r.reconciler.(ReadOnlyInterface) + + isLeader := r.IsLeaderFor(types.NamespacedName{ + Namespace: namespace, + Name: name, + }) + + return &state{ + key: key, + namespace: namespace, + name: name, + reconciler: r.reconciler, + roi: roi, + isROI: isROI, + isLeader: isLeader, + }, nil +} + +// isNotLeaderNorObserver checks to see if this reconciler with the current +// state is enabled to do any work or not. +// isNotLeaderNorObserver returns true when there is no work possible for the +// reconciler. +func (s *state) isNotLeaderNorObserver() bool { + if !s.isLeader && !s.isROI { + // If we are not the leader, and we don't implement the ReadOnly + // interface, then take a fast-path out. + return true + } + return false +} + +func (s *state) reconcileMethodFor(o *v1beta1.StepAction) (string, doReconcile) { + if o.GetDeletionTimestamp().IsZero() { + if s.isLeader { + return reconciler.DoReconcileKind, s.reconciler.ReconcileKind + } else if s.isROI { + return reconciler.DoObserveKind, s.roi.ObserveKind + } + } else if fin, ok := s.reconciler.(Finalizer); s.isLeader && ok { + return reconciler.DoFinalizeKind, fin.FinalizeKind + } + return "unknown", nil +} diff --git a/pkg/client/listers/pipeline/v1beta1/expansion_generated.go b/pkg/client/listers/pipeline/v1beta1/expansion_generated.go index db5d996e615..0fe1994d1d8 100644 --- a/pkg/client/listers/pipeline/v1beta1/expansion_generated.go +++ b/pkg/client/listers/pipeline/v1beta1/expansion_generated.go @@ -46,6 +46,14 @@ type PipelineRunListerExpansion interface{} // PipelineRunNamespaceLister. type PipelineRunNamespaceListerExpansion interface{} +// StepActionListerExpansion allows custom methods to be added to +// StepActionLister. +type StepActionListerExpansion interface{} + +// StepActionNamespaceListerExpansion allows custom methods to be added to +// StepActionNamespaceLister. +type StepActionNamespaceListerExpansion interface{} + // TaskListerExpansion allows custom methods to be added to // TaskLister. type TaskListerExpansion interface{} diff --git a/pkg/client/listers/pipeline/v1beta1/stepaction.go b/pkg/client/listers/pipeline/v1beta1/stepaction.go new file mode 100644 index 00000000000..1925738258d --- /dev/null +++ b/pkg/client/listers/pipeline/v1beta1/stepaction.go @@ -0,0 +1,99 @@ +/* +Copyright 2020 The Tekton Authors + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Code generated by lister-gen. DO NOT EDIT. + +package v1beta1 + +import ( + v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + "k8s.io/apimachinery/pkg/api/errors" + "k8s.io/apimachinery/pkg/labels" + "k8s.io/client-go/tools/cache" +) + +// StepActionLister helps list StepActions. +// All objects returned here must be treated as read-only. +type StepActionLister interface { + // List lists all StepActions in the indexer. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.StepAction, err error) + // StepActions returns an object that can list and get StepActions. + StepActions(namespace string) StepActionNamespaceLister + StepActionListerExpansion +} + +// stepActionLister implements the StepActionLister interface. +type stepActionLister struct { + indexer cache.Indexer +} + +// NewStepActionLister returns a new StepActionLister. +func NewStepActionLister(indexer cache.Indexer) StepActionLister { + return &stepActionLister{indexer: indexer} +} + +// List lists all StepActions in the indexer. +func (s *stepActionLister) List(selector labels.Selector) (ret []*v1beta1.StepAction, err error) { + err = cache.ListAll(s.indexer, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.StepAction)) + }) + return ret, err +} + +// StepActions returns an object that can list and get StepActions. +func (s *stepActionLister) StepActions(namespace string) StepActionNamespaceLister { + return stepActionNamespaceLister{indexer: s.indexer, namespace: namespace} +} + +// StepActionNamespaceLister helps list and get StepActions. +// All objects returned here must be treated as read-only. +type StepActionNamespaceLister interface { + // List lists all StepActions in the indexer for a given namespace. + // Objects returned here must be treated as read-only. + List(selector labels.Selector) (ret []*v1beta1.StepAction, err error) + // Get retrieves the StepAction from the indexer for a given namespace and name. + // Objects returned here must be treated as read-only. + Get(name string) (*v1beta1.StepAction, error) + StepActionNamespaceListerExpansion +} + +// stepActionNamespaceLister implements the StepActionNamespaceLister +// interface. +type stepActionNamespaceLister struct { + indexer cache.Indexer + namespace string +} + +// List lists all StepActions in the indexer for a given namespace. +func (s stepActionNamespaceLister) List(selector labels.Selector) (ret []*v1beta1.StepAction, err error) { + err = cache.ListAllByNamespace(s.indexer, s.namespace, selector, func(m interface{}) { + ret = append(ret, m.(*v1beta1.StepAction)) + }) + return ret, err +} + +// Get retrieves the StepAction from the indexer for a given namespace and name. +func (s stepActionNamespaceLister) Get(name string) (*v1beta1.StepAction, error) { + obj, exists, err := s.indexer.GetByKey(s.namespace + "/" + name) + if err != nil { + return nil, err + } + if !exists { + return nil, errors.NewNotFound(v1beta1.Resource("stepaction"), name) + } + return obj.(*v1beta1.StepAction), nil +} diff --git a/pkg/reconciler/apiserver/apiserver.go b/pkg/reconciler/apiserver/apiserver.go index 8489f6e12af..6367d6da719 100644 --- a/pkg/reconciler/apiserver/apiserver.go +++ b/pkg/reconciler/apiserver/apiserver.go @@ -65,6 +65,13 @@ func DryRunValidate(ctx context.Context, namespace string, obj runtime.Object, t if _, err := tekton.TektonV1alpha1().StepActions(namespace).Create(ctx, dryRunObj, metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}); err != nil { return handleDryRunCreateErr(err, obj.Name) } + case *v1beta1.StepAction: + dryRunObj := obj.DeepCopy() + dryRunObj.Name = dryRunObjName + dryRunObj.Namespace = namespace // Make sure the namespace is the same as the StepAction + if _, err := tekton.TektonV1beta1().StepActions(namespace).Create(ctx, dryRunObj, metav1.CreateOptions{DryRun: []string{metav1.DryRunAll}}); err != nil { + return handleDryRunCreateErr(err, obj.Name) + } default: return fmt.Errorf("unsupported object GVK %s", obj.GetObjectKind().GroupVersionKind()) } diff --git a/pkg/reconciler/apiserver/apiserver_test.go b/pkg/reconciler/apiserver/apiserver_test.go index 7233a145d27..1ed2aa3eac6 100644 --- a/pkg/reconciler/apiserver/apiserver_test.go +++ b/pkg/reconciler/apiserver/apiserver_test.go @@ -38,6 +38,9 @@ func TestDryRunCreate_Valid_DifferentGVKs(t *testing.T) { }, { name: "v1alpha1 stepaction", obj: &v1alpha1.StepAction{}, + }, { + name: "v1beta1 stepaction", + obj: &v1beta1.StepAction{}, }, { name: "unsupported gvk", obj: &v1beta1.ClusterTask{}, @@ -79,6 +82,10 @@ func TestDryRunCreate_Invalid_DifferentGVKs(t *testing.T) { name: "v1alpha1 stepaction", obj: &v1alpha1.StepAction{}, wantErr: apiserver.ErrReferencedObjectValidationFailed, + }, { + name: "v1beta1 stepaction", + obj: &v1beta1.StepAction{}, + wantErr: apiserver.ErrReferencedObjectValidationFailed, }, { name: "unsupported gvk", obj: &v1beta1.ClusterTask{}, diff --git a/pkg/reconciler/taskrun/resources/taskref.go b/pkg/reconciler/taskrun/resources/taskref.go index 872af8a787a..fa7e1200c05 100644 --- a/pkg/reconciler/taskrun/resources/taskref.go +++ b/pkg/reconciler/taskrun/resources/taskref.go @@ -141,7 +141,7 @@ func GetStepActionFunc(tekton clientset.Interface, k8s kubernetes.Interface, req if step.Ref != nil && step.Ref.Resolver != "" && requester != nil { // Return an inline function that implements GetStepAction by calling Resolver.Get with the specified StepAction type and // casting it to a StepAction. - return func(ctx context.Context, name string) (*v1alpha1.StepAction, *v1.RefSource, error) { + return func(ctx context.Context, name string) (*v1beta1.StepAction, *v1.RefSource, error) { // Perform params replacements for StepAction resolver params ApplyParameterSubstitutionInResolverParams(tr, step) resolverPayload := remoteresource.ResolverPayload{ @@ -221,17 +221,33 @@ func resolveTask(ctx context.Context, resolver remote.Resolver, name, namespace return taskObj, refSource, vr, nil } -func resolveStepAction(ctx context.Context, resolver remote.Resolver, name, namespace string, k8s kubernetes.Interface, tekton clientset.Interface) (*v1alpha1.StepAction, *v1.RefSource, error) { +func resolveStepAction(ctx context.Context, resolver remote.Resolver, name, namespace string, k8s kubernetes.Interface, tekton clientset.Interface) (*v1beta1.StepAction, *v1.RefSource, error) { obj, refSource, err := resolver.Get(ctx, "StepAction", name) if err != nil { return nil, nil, err } - switch obj := obj.(type) { //nolint:gocritic - case *v1alpha1.StepAction: + switch obj := obj.(type) { + case *v1beta1.StepAction: if err := apiserver.DryRunValidate(ctx, namespace, obj, tekton); err != nil { return nil, nil, err } return obj, refSource, nil + case *v1alpha1.StepAction: + obj.SetDefaults(ctx) + if err := apiserver.DryRunValidate(ctx, namespace, obj, tekton); err != nil { + return nil, nil, err + } + v1BetaStepAction := v1beta1.StepAction{ + TypeMeta: metav1.TypeMeta{ + Kind: "StepAction", + APIVersion: "tekton.dev/v1beta1", + }, + } + err := obj.ConvertTo(ctx, &v1BetaStepAction) + if err != nil { + return nil, nil, err + } + return &v1BetaStepAction, refSource, nil } return nil, nil, errors.New("resource is not a StepAction") } @@ -329,12 +345,12 @@ type LocalStepActionRefResolver struct { // GetStepAction will resolve a StepAction from the local cluster using a versioned Tekton client. // It will return an error if it can't find an appropriate StepAction for any reason. -func (l *LocalStepActionRefResolver) GetStepAction(ctx context.Context, name string) (*v1alpha1.StepAction, *v1.RefSource, error) { +func (l *LocalStepActionRefResolver) GetStepAction(ctx context.Context, name string) (*v1beta1.StepAction, *v1.RefSource, error) { // If we are going to resolve this reference locally, we need a namespace scope. if l.Namespace == "" { return nil, nil, fmt.Errorf("must specify namespace to resolve reference to step action %s", name) } - stepAction, err := l.Tektonclient.TektonV1alpha1().StepActions(l.Namespace).Get(ctx, name, metav1.GetOptions{}) + stepAction, err := l.Tektonclient.TektonV1beta1().StepActions(l.Namespace).Get(ctx, name, metav1.GetOptions{}) if err != nil { return nil, nil, err } diff --git a/pkg/reconciler/taskrun/resources/taskref_test.go b/pkg/reconciler/taskrun/resources/taskref_test.go index 9bf6c18ca38..643c5754e66 100644 --- a/pkg/reconciler/taskrun/resources/taskref_test.go +++ b/pkg/reconciler/taskrun/resources/taskref_test.go @@ -54,16 +54,16 @@ import ( ) var ( - simpleNamespacedStepAction = &v1alpha1.StepAction{ + simpleNamespacedStepAction = &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "simple", Namespace: "default", }, TypeMeta: metav1.TypeMeta{ - APIVersion: "tekton.dev/v1alpha1", + APIVersion: "tekton.dev/v1beta1", Kind: "StepAction", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "something", }, } @@ -608,13 +608,13 @@ func TestStepActionRef(t *testing.T) { name: "local-step-action", namespace: "default", stepactions: []runtime.Object{ - &v1alpha1.StepAction{ + &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "simple", Namespace: "default", }, }, - &v1alpha1.StepAction{ + &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "sample", Namespace: "default", @@ -624,7 +624,7 @@ func TestStepActionRef(t *testing.T) { ref: &v1.Ref{ Name: "simple", }, - expected: &v1alpha1.StepAction{ + expected: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "simple", Namespace: "default", @@ -681,7 +681,7 @@ func TestStepActionRef_Error(t *testing.T) { name: "local-step-action-missing-namespace", namespace: "", stepactions: []runtime.Object{ - &v1alpha1.StepAction{ + &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "simple", Namespace: "default", @@ -887,16 +887,24 @@ func TestGetStepActionFunc_RemoteResolution_Success(t *testing.T) { testcases := []struct { name string stepActionYAML string - wantStepAction *v1alpha1.StepAction + wantStepAction *v1beta1.StepAction wantErr bool }{{ - name: "remote StepAction", + name: "remote StepAction v1alpha1", stepActionYAML: strings.Join([]string{ "kind: StepAction", "apiVersion: tekton.dev/v1alpha1", stepActionYAMLString, }, "\n"), - wantStepAction: parse.MustParseV1alpha1StepAction(t, stepActionYAMLString), + wantStepAction: parse.MustParseV1beta1StepAction(t, stepActionYAMLString), + }, { + name: "remote StepAction v1beta1", + stepActionYAML: strings.Join([]string{ + "kind: StepAction", + "apiVersion: tekton.dev/v1beta1", + stepActionYAMLString, + }, "\n"), + wantStepAction: parse.MustParseV1beta1StepAction(t, stepActionYAMLString), }} for _, tc := range testcases { t.Run(tc.name, func(t *testing.T) { diff --git a/pkg/reconciler/taskrun/resources/taskspec.go b/pkg/reconciler/taskrun/resources/taskspec.go index 955154911c9..f8f856da4ff 100644 --- a/pkg/reconciler/taskrun/resources/taskspec.go +++ b/pkg/reconciler/taskrun/resources/taskspec.go @@ -22,7 +22,7 @@ import ( "fmt" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" clientset "github.com/tektoncd/pipeline/pkg/client/clientset/versioned" resolutionutil "github.com/tektoncd/pipeline/pkg/internal/resolution" remoteresource "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" @@ -42,7 +42,7 @@ type ResolvedTask struct { } // GetStepAction is a function used to retrieve StepActions. -type GetStepAction func(context.Context, string) (*v1alpha1.StepAction, *v1.RefSource, error) +type GetStepAction func(context.Context, string) (*v1beta1.StepAction, *v1.RefSource, error) // GetTask is a function used to retrieve Tasks. // VerificationResult is the result from trusted resources if the feature is enabled. diff --git a/pkg/reconciler/taskrun/resources/taskspec_test.go b/pkg/reconciler/taskrun/resources/taskspec_test.go index 361ce2f0050..0c53fff2330 100644 --- a/pkg/reconciler/taskrun/resources/taskspec_test.go +++ b/pkg/reconciler/taskrun/resources/taskspec_test.go @@ -25,7 +25,7 @@ import ( "github.com/google/go-cmp/cmp" "github.com/google/go-cmp/cmp/cmpopts" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" "github.com/tektoncd/pipeline/pkg/client/clientset/versioned/fake" "github.com/tektoncd/pipeline/pkg/reconciler/taskrun/resources" "github.com/tektoncd/pipeline/pkg/trustedresources" @@ -303,7 +303,7 @@ func TestGetStepActionsData(t *testing.T) { tests := []struct { name string tr *v1.TaskRun - stepAction *v1alpha1.StepAction + stepAction *v1beta1.StepAction want []v1.Step }{{ name: "step-action-with-command-args", @@ -323,12 +323,12 @@ func TestGetStepActionsData(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{ + stepAction: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "stepAction", Namespace: "default", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "myimage", Command: []string{"ls"}, Args: []string{"-lh"}, @@ -365,12 +365,12 @@ func TestGetStepActionsData(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{ + stepAction: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "stepActionWithScript", Namespace: "default", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "myimage", Script: "ls", }, @@ -396,12 +396,12 @@ func TestGetStepActionsData(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{ + stepAction: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "stepActionWithEnv", Namespace: "default", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "myimage", Env: []corev1.EnvVar{{ Name: "env1", @@ -433,12 +433,12 @@ func TestGetStepActionsData(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{ + stepAction: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "stepActionWithScript", Namespace: "default", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "myimage", Script: "ls", Results: []v1.StepResult{{ @@ -472,12 +472,12 @@ func TestGetStepActionsData(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{ + stepAction: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "stepAction", Namespace: "default", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "myimage", Command: []string{"ls"}, Args: []string{"-lh"}, @@ -510,12 +510,12 @@ func TestGetStepActionsData(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{ + stepAction: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "stepAction", Namespace: "default", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "myimage", Command: []string{"ls"}, Args: []string{"-lh"}, @@ -574,12 +574,12 @@ func TestGetStepActionsData(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{ + stepAction: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "stepAction", Namespace: "default", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "myimage", Args: []string{"$(params.string-param)", "$(params.array-param[0])", "$(params.array-param[1])", "$(params.array-param[*])", "$(params.object-param.key)"}, Params: v1.ParamSpecs{{ @@ -645,12 +645,12 @@ func TestGetStepActionsData(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{ + stepAction: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "stepAction", Namespace: "default", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "myimage", Args: []string{"$(params.string-param)", "$(params.array-param[0])", "$(params.array-param[1])", "$(params.array-param[*])", "$(params.object-param.key)"}, Params: v1.ParamSpecs{{ @@ -687,12 +687,12 @@ func TestGetStepActionsData(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{ + stepAction: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "stepAction", Namespace: "default", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "myimage", Args: []string{"$(params.string-param)", "$(params.array-param[0])", "$(params.array-param[1])", "$(params.array-param[*])", "$(params.object-param.key)"}, Params: v1.ParamSpecs{{ @@ -777,12 +777,12 @@ func TestGetStepActionsData(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{ + stepAction: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "stepAction", Namespace: "default", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "myimage", Args: []string{"$(params.string-param)", "$(params.array-param[0])", "$(params.array-param[1])", "$(params.array-param[*])", "$(params.object-param.key)", "$(params.object-param.key2)", "$(params.object-param.key3)"}, Params: v1.ParamSpecs{{ @@ -848,12 +848,12 @@ func TestGetStepActionsData(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{ + stepAction: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "stepAction", Namespace: "default", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "myimage", Args: []string{"echo", "$(params.stringparam)"}, Params: v1.ParamSpecs{{ @@ -908,12 +908,12 @@ func TestGetStepActionsData(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{ + stepAction: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "stepAction", Namespace: "default", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "myimage", Args: []string{"$(params.string-param)", "$(params.array-param[0])", "$(params.array-param[1])", "$(params.array-param[*])", "$(params.object-param.key)"}, Command: []string{"$(params[\"string-param\"])", "$(params[\"array-param\"][0])"}, @@ -980,7 +980,7 @@ func TestGetStepActionsData_Error(t *testing.T) { tests := []struct { name string tr *v1.TaskRun - stepAction *v1alpha1.StepAction + stepAction *v1beta1.StepAction expectedError error }{{ name: "namespace missing error", @@ -998,7 +998,7 @@ func TestGetStepActionsData_Error(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{}, + stepAction: &v1beta1.StepAction{}, expectedError: errors.New("must specify namespace to resolve reference to step action stepActionError"), }, { name: "params missing", @@ -1017,12 +1017,12 @@ func TestGetStepActionsData_Error(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{ + stepAction: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "stepaction", Namespace: "default", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "myimage", Params: v1.ParamSpecs{{ Name: "string-param", @@ -1052,12 +1052,12 @@ func TestGetStepActionsData_Error(t *testing.T) { }, }, }, - stepAction: &v1alpha1.StepAction{ + stepAction: &v1beta1.StepAction{ ObjectMeta: metav1.ObjectMeta{ Name: "stepaction", Namespace: "default", }, - Spec: v1alpha1.StepActionSpec{ + Spec: v1beta1.StepActionSpec{ Image: "myimage", }, }, diff --git a/pkg/reconciler/taskrun/taskrun_test.go b/pkg/reconciler/taskrun/taskrun_test.go index ce23ebfa491..85a4848d22d 100644 --- a/pkg/reconciler/taskrun/taskrun_test.go +++ b/pkg/reconciler/taskrun/taskrun_test.go @@ -2099,7 +2099,7 @@ spec: resolver: bar `) - stepAction := parse.MustParseV1alpha1StepAction(t, ` + stepAction := parse.MustParseV1beta1StepAction(t, ` metadata: name: stepAction namespace: foo @@ -2134,7 +2134,7 @@ spec: clients := testAssets.Clients err = c.Reconciler.Reconcile(testAssets.Ctx, fmt.Sprintf("%s/%s", tr.Namespace, tr.Name)) if controller.IsPermanentError(err) { - t.Errorf("Not expected permanent error but got %t", err) + t.Errorf("Not expected permanent error but got %v", err) } reconciledRun, err := clients.Pipeline.TektonV1().TaskRuns(tr.Namespace).Get(testAssets.Ctx, tr.Name, metav1.GetOptions{}) if err != nil { @@ -2159,7 +2159,7 @@ spec: resolver: bar `)} - stepAction := parse.MustParseV1alpha1StepAction(t, ` + stepAction := parse.MustParseV1beta1StepAction(t, ` metadata: name: stepAction namespace: foo @@ -3549,7 +3549,7 @@ spec: - name: inlined-step image: "inlined-image" `) - stepAction := parse.MustParseV1alpha1StepAction(t, ` + stepAction := parse.MustParseV1beta1StepAction(t, ` metadata: name: stepAction namespace: foo @@ -3559,7 +3559,7 @@ spec: securityContext: privileged: true `) - stepAction2 := parse.MustParseV1alpha1StepAction(t, ` + stepAction2 := parse.MustParseV1beta1StepAction(t, ` metadata: name: stepAction2 namespace: foo @@ -3569,7 +3569,7 @@ spec: `) d := test.Data{ TaskRuns: []*v1.TaskRun{taskRun}, - StepActions: []*v1alpha1.StepAction{stepAction, stepAction2}, + StepActions: []*v1beta1.StepAction{stepAction, stepAction2}, ConfigMaps: []*corev1.ConfigMap{ { ObjectMeta: metav1.ObjectMeta{Name: config.GetFeatureFlagsConfigName(), Namespace: system.Namespace()}, @@ -3659,7 +3659,7 @@ func TestStepActionRefParams(t *testing.T) { tests := []struct { name string taskRun *v1.TaskRun - stepAction *v1alpha1.StepAction + stepAction *v1beta1.StepAction want []v1.Step }{{ name: "params propagated from taskrun", @@ -3689,7 +3689,7 @@ spec: - name: object-param value: $(params.objectparam[*]) `), - stepAction: parse.MustParseV1alpha1StepAction(t, ` + stepAction: parse.MustParseV1beta1StepAction(t, ` metadata: name: stepAction namespace: foo @@ -3734,7 +3734,7 @@ spec: - name: stringparam value: "step string param" `), - stepAction: parse.MustParseV1alpha1StepAction(t, ` + stepAction: parse.MustParseV1beta1StepAction(t, ` metadata: name: stepAction namespace: foo @@ -3767,7 +3767,7 @@ spec: name: stepAction name: step1 `), - stepAction: parse.MustParseV1alpha1StepAction(t, ` + stepAction: parse.MustParseV1beta1StepAction(t, ` metadata: name: stepAction namespace: foo @@ -3798,7 +3798,7 @@ spec: name: stepAction name: step1 `), - stepAction: parse.MustParseV1alpha1StepAction(t, ` + stepAction: parse.MustParseV1beta1StepAction(t, ` metadata: name: stepAction namespace: foo @@ -3844,7 +3844,7 @@ spec: - name: object-param value: $(params.objectparam[*]) `), - stepAction: parse.MustParseV1alpha1StepAction(t, ` + stepAction: parse.MustParseV1beta1StepAction(t, ` metadata: name: stepAction namespace: foo @@ -3881,7 +3881,7 @@ spec: name: stepAction name: step1 `), - stepAction: parse.MustParseV1alpha1StepAction(t, ` + stepAction: parse.MustParseV1beta1StepAction(t, ` metadata: name: stepAction namespace: foo @@ -3918,7 +3918,7 @@ spec: t.Run(tt.name, func(t *testing.T) { d := test.Data{ TaskRuns: []*v1.TaskRun{tt.taskRun}, - StepActions: []*v1alpha1.StepAction{tt.stepAction}, + StepActions: []*v1beta1.StepAction{tt.stepAction}, ConfigMaps: []*corev1.ConfigMap{ { ObjectMeta: metav1.ObjectMeta{Name: config.GetFeatureFlagsConfigName(), Namespace: system.Namespace()}, diff --git a/test/clients.go b/test/clients.go index 0a0a4f21400..dc0424a5275 100644 --- a/test/clients.go +++ b/test/clients.go @@ -68,7 +68,7 @@ type clients struct { V1TaskClient v1.TaskInterface V1TaskRunClient v1.TaskRunInterface V1PipelineRunClient v1.PipelineRunInterface - V1alpha1StepActionClient v1alpha1.StepActionInterface + V1beta1StepActionClient v1beta1.StepActionInterface } // newClients instantiates and returns several clientsets required for making requests to the @@ -110,6 +110,6 @@ func newClients(t *testing.T, configPath, clusterName, namespace string) *client c.V1TaskClient = cs.TektonV1().Tasks(namespace) c.V1TaskRunClient = cs.TektonV1().TaskRuns(namespace) c.V1PipelineRunClient = cs.TektonV1().PipelineRuns(namespace) - c.V1alpha1StepActionClient = cs.TektonV1alpha1().StepActions(namespace) + c.V1beta1StepActionClient = cs.TektonV1beta1().StepActions(namespace) return c } diff --git a/test/controller.go b/test/controller.go index 93a3840ae86..d4cc5506135 100644 --- a/test/controller.go +++ b/test/controller.go @@ -37,10 +37,10 @@ import ( fakepipelineruninformer "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1/pipelinerun/fake" faketaskinformer "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1/task/fake" faketaskruninformer "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1/taskrun/fake" - fakestepactioninformer "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1alpha1/stepaction/fake" fakeverificationpolicyinformer "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1alpha1/verificationpolicy/fake" fakeclustertaskinformer "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1beta1/clustertask/fake" fakecustomruninformer "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1beta1/customrun/fake" + fakestepactioninformer "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1beta1/stepaction/fake" fakeresolutionclientset "github.com/tektoncd/pipeline/pkg/client/resolution/clientset/versioned/fake" resolutioninformersv1alpha1 "github.com/tektoncd/pipeline/pkg/client/resolution/informers/externalversions/resolution/v1beta1" fakeresolutionrequestclient "github.com/tektoncd/pipeline/pkg/client/resolution/injection/client/fake" @@ -74,7 +74,7 @@ type Data struct { Pipelines []*v1.Pipeline TaskRuns []*v1.TaskRun Tasks []*v1.Task - StepActions []*v1alpha1.StepAction + StepActions []*v1beta1.StepAction ClusterTasks []*v1beta1.ClusterTask CustomRuns []*v1beta1.CustomRun Pods []*corev1.Pod @@ -104,7 +104,7 @@ type Informers struct { Run informersv1alpha1.RunInformer CustomRun informersv1beta1.CustomRunInformer Task informersv1.TaskInformer - StepAction informersv1alpha1.StepActionInformer + StepAction informersv1beta1.StepActionInformer ClusterTask informersv1beta1.ClusterTaskInformer Pod coreinformers.PodInformer ConfigMap coreinformers.ConfigMapInformer @@ -236,7 +236,7 @@ func SeedTestData(t *testing.T, ctx context.Context, d Data) (Clients, Informers c.Pipeline.PrependReactor("*", "stepactions", AddToInformer(t, i.StepAction.Informer().GetIndexer())) for _, sa := range d.StepActions { sa := sa.DeepCopy() // Avoid assumptions that the informer's copy is modified. - if _, err := c.Pipeline.TektonV1alpha1().StepActions(sa.Namespace).Create(ctx, sa, metav1.CreateOptions{}); err != nil { + if _, err := c.Pipeline.TektonV1beta1().StepActions(sa.Namespace).Create(ctx, sa, metav1.CreateOptions{}); err != nil { t.Fatal(err) } } diff --git a/test/e2e-tests-kind-prow-beta.env b/test/e2e-tests-kind-prow-beta.env index 8dae8c618fe..516f4675938 100644 --- a/test/e2e-tests-kind-prow-beta.env +++ b/test/e2e-tests-kind-prow-beta.env @@ -2,5 +2,6 @@ SKIP_INITIALIZE=true PIPELINE_FEATURE_GATE=beta EMBEDDED_STATUS_GATE=minimal RUN_YAML_TESTS=true +ENABLE_STEP_ACTIONS=true KO_DOCKER_REPO=registry.local:5000 E2E_GO_TEST_TIMEOUT=40m diff --git a/test/featureflags.go b/test/featureflags.go index 673d82cb75f..6ffa121f0ed 100644 --- a/test/featureflags.go +++ b/test/featureflags.go @@ -123,7 +123,8 @@ func getFeatureFlagsBaseOnAPIFlag(t *testing.T) *config.FeatureFlags { t.Fatalf("error creating alpha feature flags configmap: %v", err) } betaFeatureFlags, err := config.NewFeatureFlagsFromMap(map[string]string{ - "enable-api-fields": "beta", + "enable-api-fields": "beta", + "enable-step-actions": "true", }) if err != nil { t.Fatalf("error creating beta feature flags configmap: %v", err) diff --git a/test/parse/yaml.go b/test/parse/yaml.go index 68bc16e14b5..847084b9c26 100644 --- a/test/parse/yaml.go +++ b/test/parse/yaml.go @@ -35,6 +35,17 @@ kind: StepAction return &sa } +// MustParseV1beta1StepAction takes YAML and parses it into a *v1alpha1.StepAction +func MustParseV1beta1StepAction(t *testing.T, yaml string) *v1beta1.StepAction { + t.Helper() + var sa v1beta1.StepAction + yaml = `apiVersion: tekton.dev/v1beta1 +kind: StepAction +` + yaml + mustParseYAML(t, yaml, &sa) + return &sa +} + // MustParseV1beta1TaskRun takes YAML and parses it into a *v1beta1.TaskRun func MustParseV1beta1TaskRun(t *testing.T, yaml string) *v1beta1.TaskRun { t.Helper() diff --git a/test/per_feature_flags_test.go b/test/per_feature_flags_test.go index 4555d2010c9..b9b25d0e98e 100644 --- a/test/per_feature_flags_test.go +++ b/test/per_feature_flags_test.go @@ -47,8 +47,8 @@ const ( ) var ( - alphaFeatureFlags = []string{"enable-param-enum", "enable-step-actions", "keep-pod-enabled-cancel", "enable-cel-in-whenexpression", "enable-artifacts"} - betaFeatureFlags = []string{} + alphaFeatureFlags = []string{"enable-param-enum", "keep-pod-enabled-cancel", "enable-cel-in-whenexpression", "enable-artifacts"} + betaFeatureFlags = []string{"enable-step-actions"} perFeatureFlags = map[string][]string{ "alpha": alphaFeatureFlags, "beta": betaFeatureFlags, diff --git a/test/stepaction_results_test.go b/test/stepaction_results_test.go index 5c3fafa50a2..c1dd23a162b 100644 --- a/test/stepaction_results_test.go +++ b/test/stepaction_results_test.go @@ -28,7 +28,7 @@ import ( "github.com/google/go-cmp/cmp/cmpopts" "github.com/tektoncd/pipeline/pkg/apis/config" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" - v1alpha1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1alpha1" + "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" "github.com/tektoncd/pipeline/test/parse" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "knative.dev/pkg/system" @@ -49,7 +49,7 @@ func TestStepResultsStepActions(t *testing.T) { type tests struct { name string taskRunFunc func(*testing.T, string) (*v1.TaskRun, *v1.TaskRun) - stepActionFunc func(*testing.T, string) *v1alpha1.StepAction + stepActionFunc func(*testing.T, string) *v1beta1.StepAction } tds := []tests{{ @@ -80,7 +80,7 @@ func TestStepResultsStepActions(t *testing.T) { trName := taskRun.Name - _, err := c.V1alpha1StepActionClient.Create(ctx, stepAction, metav1.CreateOptions{}) + _, err := c.V1beta1StepActionClient.Create(ctx, stepAction, metav1.CreateOptions{}) if err != nil { t.Fatalf("Failed to create StepAction : %s", err) } @@ -114,9 +114,9 @@ func TestStepResultsStepActions(t *testing.T) { } } -func getStepAction(t *testing.T, namespace string) *v1alpha1.StepAction { +func getStepAction(t *testing.T, namespace string) *v1beta1.StepAction { t.Helper() - return parse.MustParseV1alpha1StepAction(t, fmt.Sprintf(` + return parse.MustParseV1beta1StepAction(t, fmt.Sprintf(` metadata: name: step-action namespace: %s From a0914c7aff068677db2a0278d71dfc4130c1d212 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 18:27:31 +0000 Subject: [PATCH 04/23] chore(deps): bump tj-actions/changed-files from 44.3.0 to 44.4.0 Bumps [tj-actions/changed-files](https://github.com/tj-actions/changed-files) from 44.3.0 to 44.4.0. - [Release notes](https://github.com/tj-actions/changed-files/releases) - [Changelog](https://github.com/tj-actions/changed-files/blob/main/HISTORY.md) - [Commits](https://github.com/tj-actions/changed-files/compare/0874344d6ebbaa00a27da73276ae7162fadcaf69...a29e8b565651ce417abb5db7164b4a2ad8b6155c) --- updated-dependencies: - dependency-name: tj-actions/changed-files dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- .github/workflows/woke.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/woke.yml b/.github/workflows/woke.yml index 67e8e264552..d952915819a 100644 --- a/.github/workflows/woke.yml +++ b/.github/workflows/woke.yml @@ -19,7 +19,7 @@ jobs: - name: Get changed files id: changed-files - uses: tj-actions/changed-files@0874344d6ebbaa00a27da73276ae7162fadcaf69 # v44.3.0 + uses: tj-actions/changed-files@a29e8b565651ce417abb5db7164b4a2ad8b6155c # v44.4.0 with: write_output_files: true files: | From 90c01d34d180dd58f2295931555156512ac6feb3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 18:27:55 +0000 Subject: [PATCH 05/23] chore(deps): bump ossf/scorecard-action from 2.3.1 to 2.3.3 Bumps [ossf/scorecard-action](https://github.com/ossf/scorecard-action) from 2.3.1 to 2.3.3. - [Release notes](https://github.com/ossf/scorecard-action/releases) - [Changelog](https://github.com/ossf/scorecard-action/blob/main/RELEASE.md) - [Commits](https://github.com/ossf/scorecard-action/compare/0864cf19026789058feabb7e87baa5f140aac736...dc50aa9510b46c811795eb24b2f1ba02a914e534) --- updated-dependencies: - dependency-name: ossf/scorecard-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/scorecard.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index f8c22808473..643504db76a 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -38,7 +38,7 @@ jobs: persist-credentials: false - name: "Run analysis" - uses: ossf/scorecard-action@0864cf19026789058feabb7e87baa5f140aac736 # v2.3.1 + uses: ossf/scorecard-action@dc50aa9510b46c811795eb24b2f1ba02a914e534 # v2.3.3 with: results_file: results.sarif results_format: sarif From e8475dc697a23368658e53f24918326cfbcaccbb Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 18:34:40 +0000 Subject: [PATCH 06/23] chore(deps): bump the all group in /tekton with 3 updates Bumps the all group in /tekton with 3 updates: chainguard/crane, tekton-releases/dogfooding/ko and tekton-releases/dogfooding/koparse. Updates `chainguard/crane` from `75e4615` to `8c2f747` Updates `tekton-releases/dogfooding/ko` from `56e89ca` to `ec2f12f` Updates `tekton-releases/dogfooding/koparse` from `ebe7626` to `b68675c` --- updated-dependencies: - dependency-name: chainguard/crane dependency-type: direct:production dependency-group: all - dependency-name: tekton-releases/dogfooding/ko dependency-type: direct:production dependency-group: all - dependency-name: tekton-releases/dogfooding/koparse dependency-type: direct:production dependency-group: all ... Signed-off-by: dependabot[bot] --- tekton/publish.yaml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tekton/publish.yaml b/tekton/publish.yaml index 93403fb0131..ec3cfb8434f 100644 --- a/tekton/publish.yaml +++ b/tekton/publish.yaml @@ -61,7 +61,7 @@ spec: steps: - name: container-registry-auth - image: cgr.dev/chainguard/crane:latest-dev@sha256:75e46150261d87e6502e4f0ce4b2ae14e256e4ed1bb2610fe146272bc270a1c4 + image: cgr.dev/chainguard/crane:latest-dev@sha256:8c2f7477a910c24bbcce01a795abb4398dad68a86a1846aa86f0c39367dc9fa2 script: | #!/bin/sh set -ex @@ -115,7 +115,7 @@ spec: cat /workspace/.ko.yaml - name: run-ko - image: gcr.io/tekton-releases/dogfooding/ko@sha256:56e89ca0d6e5f1890e6631c6e23de452aee53d59eccf2b60f2432486ac587e87 + image: gcr.io/tekton-releases/dogfooding/ko@sha256:ec2f12f2304441f22614257c761406ce923032310926df72b82e4210aed77edd env: - name: KO_DOCKER_REPO value: $(params.imageRegistry)/$(params.imageRegistryPath) @@ -169,7 +169,7 @@ spec: sed -i -e 's/\(pipeline.tekton.dev\/release\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\(app.kubernetes.io\/version\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\(version\): "devel"/\1: "$(params.versionTag)"/g' ${OUTPUT_RELEASE_DIR}/release.yaml sed -i -e 's/\(pipeline.tekton.dev\/release\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\(app.kubernetes.io\/version\): "devel"/\1: "$(params.versionTag)"/g' -e 's/\(version\): "devel"/\1: "$(params.versionTag)"/g' ${OUTPUT_RELEASE_DIR}/release.notags.yaml - name: koparse - image: gcr.io/tekton-releases/dogfooding/koparse@sha256:ebe7626bc909597e1b2858041334067044f690ea4f94b006bfb475c6ae128a01 + image: gcr.io/tekton-releases/dogfooding/koparse@sha256:b68675c9f5c936865495e76e69fe78c46a2dba9c084d5e7c064e8d40ea623cc9 script: | set -ex @@ -187,7 +187,7 @@ spec: - name: tag-images - image: cgr.dev/chainguard/crane:latest-dev@sha256:75e46150261d87e6502e4f0ce4b2ae14e256e4ed1bb2610fe146272bc270a1c4 + image: cgr.dev/chainguard/crane:latest-dev@sha256:8c2f7477a910c24bbcce01a795abb4398dad68a86a1846aa86f0c39367dc9fa2 script: | #!/bin/sh set -ex From 981c034414699d956a63590e17f8d06cc81038f6 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Mon, 13 May 2024 18:27:49 +0000 Subject: [PATCH 07/23] chore(deps): bump github/codeql-action from 3.25.3 to 3.25.5 Bumps [github/codeql-action](https://github.com/github/codeql-action) from 3.25.3 to 3.25.5. - [Release notes](https://github.com/github/codeql-action/releases) - [Changelog](https://github.com/github/codeql-action/blob/main/CHANGELOG.md) - [Commits](https://github.com/github/codeql-action/compare/d39d31e687223d841ef683f52467bd88e9b21c14...b7cec7526559c32f1616476ff32d17ba4c59b2d6) --- updated-dependencies: - dependency-name: github/codeql-action dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- .github/workflows/codeql-analysis.yml | 4 ++-- .github/workflows/scorecard.yml | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml index 09c1a441a24..3c47e062dfe 100644 --- a/.github/workflows/codeql-analysis.yml +++ b/.github/workflows/codeql-analysis.yml @@ -58,7 +58,7 @@ jobs: # Initializes the CodeQL tools for scanning. - name: Initialize CodeQL - uses: github/codeql-action/init@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 + uses: github/codeql-action/init@b7cec7526559c32f1616476ff32d17ba4c59b2d6 # v3.25.5 with: languages: ${{ matrix.language }} # If you wish to specify custom queries, you can do so here or in a config file. @@ -92,4 +92,4 @@ jobs: make -j 4 all - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 + uses: github/codeql-action/analyze@b7cec7526559c32f1616476ff32d17ba4c59b2d6 # v3.25.5 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml index 643504db76a..1d6281bd7db 100644 --- a/.github/workflows/scorecard.yml +++ b/.github/workflows/scorecard.yml @@ -61,6 +61,6 @@ jobs: # Upload the results to GitHub's code scanning dashboard. - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@d39d31e687223d841ef683f52467bd88e9b21c14 # v3.25.3 + uses: github/codeql-action/upload-sarif@b7cec7526559c32f1616476ff32d17ba4c59b2d6 # v3.25.5 with: sarif_file: results.sarif From 7528732b8e40e3f932a33f451d8428dd9b725664 Mon Sep 17 00:00:00 2001 From: Khurram Baig Date: Thu, 28 Mar 2024 07:55:50 +0530 Subject: [PATCH 08/23] Add reason tag to duration metrics Added reason tag to duration metrics. Different failures cause difference in duration of pipelineruns and taskruns. --- docs/metrics.md | 8 ++++---- pkg/pipelinerunmetrics/metrics.go | 10 ++++++---- pkg/pipelinerunmetrics/metrics_test.go | 2 ++ pkg/taskrunmetrics/metrics.go | 10 ++++++---- pkg/taskrunmetrics/metrics_test.go | 1 + 5 files changed, 19 insertions(+), 12 deletions(-) diff --git a/docs/metrics.md b/docs/metrics.md index dae43467221..68441559ead 100644 --- a/docs/metrics.md +++ b/docs/metrics.md @@ -14,13 +14,13 @@ We expose several kinds of exporters, including Prometheus, Google Stackdriver, | Name | Type | Labels/Tags | Status | |-----------------------------------------------------------------------------------------| ----------- |-------------------------------------------------| ----------- | | `tekton_pipelines_controller_pipelinerun_duration_seconds_[bucket, sum, count]` | Histogram/LastValue(Gauge) | `*pipeline`=<pipeline_name>
    `*pipelinerun`=<pipelinerun_name>
    `status`=<status>
    `namespace`=<pipelinerun-namespace> | experimental | -| `tekton_pipelines_controller_pipelinerun_taskrun_duration_seconds_[bucket, sum, count]` | Histogram/LastValue(Gauge) | `*pipeline`=<pipeline_name>
    `*pipelinerun`=<pipelinerun_name>
    `status`=<status>
    `*task`=<task_name>
    `*taskrun`=<taskrun_name>
    `namespace`=<pipelineruns-taskruns-namespace> | experimental | -| `tekton_pipelines_controller_pipelinerun_count` | Counter | `status`=<status> | deprecate | +| `tekton_pipelines_controller_pipelinerun_taskrun_duration_seconds_[bucket, sum, count]` | Histogram/LastValue(Gauge) | `*pipeline`=<pipeline_name>
    `*pipelinerun`=<pipelinerun_name>
    `status`=<status>
    `*task`=<task_name>
    `*taskrun`=<taskrun_name>
    `namespace`=<pipelineruns-taskruns-namespace>
    `*reason`=<reason> | experimental | +| `tekton_pipelines_controller_pipelinerun_count` | Counter | `status`=<status>
    `*reason`=<reason> | deprecate | | `tekton_pipelines_controller_pipelinerun_total` | Counter | `status`=<status> | experimental | | `tekton_pipelines_controller_running_pipelineruns_count` | Gauge | | deprecate | | `tekton_pipelines_controller_running_pipelineruns` | Gauge | | experimental | -| `tekton_pipelines_controller_taskrun_duration_seconds_[bucket, sum, count]` | Histogram/LastValue(Gauge) | `status`=<status>
    `*task`=<task_name>
    `*taskrun`=<taskrun_name>
    `namespace`=<pipelineruns-taskruns-namespace> | experimental | -| `tekton_pipelines_controller_taskrun_count` | Counter | `status`=<status> | deprecate | +| `tekton_pipelines_controller_taskrun_duration_seconds_[bucket, sum, count]` | Histogram/LastValue(Gauge) | `status`=<status>
    `*task`=<task_name>
    `*taskrun`=<taskrun_name>
    `namespace`=<pipelineruns-taskruns-namespace>
    `*reason`=<reason> | experimental | +| `tekton_pipelines_controller_taskrun_count` | Counter | `status`=<status>
    `*reason`=<reason> | deprecate | | `tekton_pipelines_controller_taskrun_total` | Counter | `status`=<status> | experimental | | `tekton_pipelines_controller_running_taskruns_count` | Gauge | | deprecate | | `tekton_pipelines_controller_running_taskruns` | Gauge | | experimental | diff --git a/pkg/pipelinerunmetrics/metrics.go b/pkg/pipelinerunmetrics/metrics.go index b389cf4907b..c89428bd67f 100644 --- a/pkg/pipelinerunmetrics/metrics.go +++ b/pkg/pipelinerunmetrics/metrics.go @@ -174,6 +174,12 @@ func viewRegister(cfg *config.Metrics) error { } } + prCountViewTags := []tag.Key{statusTag} + if cfg.CountWithReason { + prCountViewTags = append(prCountViewTags, reasonTag) + prunTag = append(prunTag, reasonTag) + } + prDurationView = &view.View{ Description: prDuration.Description(), Measure: prDuration, @@ -181,10 +187,6 @@ func viewRegister(cfg *config.Metrics) error { TagKeys: append([]tag.Key{statusTag, namespaceTag}, prunTag...), } - prCountViewTags := []tag.Key{statusTag} - if cfg.CountWithReason { - prCountViewTags = append(prCountViewTags, reasonTag) - } prCountView = &view.View{ Description: prCount.Description(), Measure: prCount, diff --git a/pkg/pipelinerunmetrics/metrics_test.go b/pkg/pipelinerunmetrics/metrics_test.go index 5a7c757e512..0633335008a 100644 --- a/pkg/pipelinerunmetrics/metrics_test.go +++ b/pkg/pipelinerunmetrics/metrics_test.go @@ -339,6 +339,7 @@ func TestRecordPipelineRunDurationCount(t *testing.T) { "pipeline": "pipeline-1", "pipelinerun": "pipelinerun-1", "namespace": "ns", + "reason": "Failed", "status": "failed", }, expectedCountTags: map[string]string{ @@ -375,6 +376,7 @@ func TestRecordPipelineRunDurationCount(t *testing.T) { "pipelinerun": "pipelinerun-1", "namespace": "ns", "status": "cancelled", + "reason": ReasonCancelled.String(), }, expectedCountTags: map[string]string{ "status": "cancelled", diff --git a/pkg/taskrunmetrics/metrics.go b/pkg/taskrunmetrics/metrics.go index c50dc4e6788..050398b24a6 100644 --- a/pkg/taskrunmetrics/metrics.go +++ b/pkg/taskrunmetrics/metrics.go @@ -212,6 +212,12 @@ func viewRegister(cfg *config.Metrics) error { } } + trCountViewTags := []tag.Key{statusTag} + if cfg.CountWithReason { + trCountViewTags = append(trCountViewTags, reasonTag) + trunTag = append(trunTag, reasonTag) + } + trDurationView = &view.View{ Description: trDuration.Description(), Measure: trDuration, @@ -225,10 +231,6 @@ func viewRegister(cfg *config.Metrics) error { TagKeys: append([]tag.Key{statusTag, namespaceTag}, append(trunTag, prunTag...)...), } - trCountViewTags := []tag.Key{statusTag} - if cfg.CountWithReason { - trCountViewTags = append(trCountViewTags, reasonTag) - } trCountView = &view.View{ Description: trCount.Description(), Measure: trCount, diff --git a/pkg/taskrunmetrics/metrics_test.go b/pkg/taskrunmetrics/metrics_test.go index e9ce6743e8d..e58a2dcb849 100644 --- a/pkg/taskrunmetrics/metrics_test.go +++ b/pkg/taskrunmetrics/metrics_test.go @@ -391,6 +391,7 @@ func TestRecordTaskRunDurationCount(t *testing.T) { "task": "task-1", "taskrun": "taskrun-1", "namespace": "ns", + "reason": "TaskRunImagePullFailed", "status": "failed", }, expectedCountTags: map[string]string{ From 19cc5c22ee9d955c18fa589918869289e76bbf88 Mon Sep 17 00:00:00 2001 From: Chitrang Patel Date: Wed, 15 May 2024 10:22:06 -0400 Subject: [PATCH 09/23] Deprecate current resolution framework This PR updates the Godoc to declare the existing resolution as deprecated. The upgraded framework was made available in `pkg/remoteresolution` in a prior PR. --- docs/deprecations.md | 1 + docs/how-to-write-a-resolver.md | 8 ++++---- docs/resolver-reference.md | 2 +- docs/resolver-template/README.md | 2 +- docs/resolver-template/cmd/demoresolver/main.go | 1 + pkg/resolution/common/interface.go | 4 ++++ pkg/resolution/resolver/bundle/resolver.go | 2 ++ pkg/resolution/resolver/cluster/resolver.go | 2 ++ pkg/resolution/resolver/framework/interface.go | 2 ++ pkg/resolution/resolver/framework/reconciler.go | 2 ++ pkg/resolution/resolver/git/resolver.go | 2 ++ pkg/resolution/resolver/http/resolver.go | 2 ++ pkg/resolution/resolver/hub/resolver.go | 2 ++ pkg/resolution/resource/crd_resource.go | 4 ++++ pkg/resolution/resource/request.go | 4 ++++ 15 files changed, 34 insertions(+), 6 deletions(-) diff --git a/docs/deprecations.md b/docs/deprecations.md index 8f51ee1ac46..34a6bc6c937 100644 --- a/docs/deprecations.md +++ b/docs/deprecations.md @@ -28,6 +28,7 @@ The following features are deprecated but have not yet been removed. | [The `default-cloud-events-sink` setting in the `config-defaults` configMap is deprecated](https://github.com/tektoncd/pipeline/pull/6883) in favour of the new `config-events` configMap. | v0.50.0 | N/A | v0.59.0 | | [v1beta1 Tasks, TaskRuns, Pipelines, and PipelineRuns are deprecated in favor of v1](https://github.com/tektoncd/pipeline/issues/5541) | v0.50.0 | Beta | v0.62.0 | | [The `disable-affinity-assistant` feature flag is deprecated in favor of the `coschedule` feature flag](https://github.com/tektoncd/pipeline/issues/6988) | v0.51.0 | N/A | April 27, 2024 | +| The `resolver framework` is [deprecated](https://github.com/tektoncd/pipeline/pull/7945) in favor of an [upgraded framework](https://github.com/tektoncd/pipeline/pull/7910) | v0.60.0 | N/A | v0.72. | ### v1beta1 deprecation diff --git a/docs/how-to-write-a-resolver.md b/docs/how-to-write-a-resolver.md index efa9ee61654..772f1e0157f 100644 --- a/docs/how-to-write-a-resolver.md +++ b/docs/how-to-write-a-resolver.md @@ -119,7 +119,7 @@ type resolver struct {} ``` {{% /tab %}} -{{% tab "Previous Framework" %}} +{{% tab "Previous Framework (Deprecated)" %}} ```go package main @@ -232,7 +232,7 @@ import ( ``` {{% /tab %}} -{{% tab "Previous Framework" %}} +{{% tab "Previous Framework (Deprecated)" %}} ```go import ( @@ -273,7 +273,7 @@ func (r *resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestS ``` {{% /tab %}} -{{% tab "Previous Framework" %}} +{{% tab "Previous Framework (Deprecated)" %}} ```go // ValidateParams ensures that the params from a request are as expected. @@ -354,7 +354,7 @@ func (*myResolvedResource) RefSource() *pipelinev1.RefSource { {{% /tab %}} -{{% tab "Previous Framework" %}} +{{% tab "Previous Framework (Deprecated)" %}} ```go diff --git a/docs/resolver-reference.md b/docs/resolver-reference.md index f2d62e22cf0..9d38bc87606 100644 --- a/docs/resolver-reference.md +++ b/docs/resolver-reference.md @@ -35,7 +35,7 @@ configuration for the framework to get a resolver running. {{% /tab %}} -{{% tab "Previous Framework" %}} +{{% tab "Previous Framework (Deprecated)" %}} | Method to Implement | Description | |----------------------|-------------| diff --git a/docs/resolver-template/README.md b/docs/resolver-template/README.md index 829f9845fa1..1469403a20f 100644 --- a/docs/resolver-template/README.md +++ b/docs/resolver-template/README.md @@ -26,7 +26,7 @@ The entire program for the `latest` framework is defined in implementations of all the methods defined by the [`framework.Resolver` interface](../../pkg/remoteresolution/resolver/framework/interface.go). -If you choose to use the previous framework (soon to be deprecated) is defined in +If you choose to use the previous framework (deprecated) is defined in [`./cmd/demoresolver/main.go`](./cmd/demoresolver/main.go) and provides stub implementations of all the methods defined by the [`framework.Resolver` interface](../../pkg/resolution/resolver/framework/interface.go). diff --git a/docs/resolver-template/cmd/demoresolver/main.go b/docs/resolver-template/cmd/demoresolver/main.go index 4c11d7164c2..881be8ba961 100644 --- a/docs/resolver-template/cmd/demoresolver/main.go +++ b/docs/resolver-template/cmd/demoresolver/main.go @@ -32,6 +32,7 @@ func main() { ) } +// Deprecated type resolver struct{} // Initialize sets up any dependencies needed by the resolver. None atm. diff --git a/pkg/resolution/common/interface.go b/pkg/resolution/common/interface.go index 3a1968f3695..82bfda68590 100644 --- a/pkg/resolution/common/interface.go +++ b/pkg/resolution/common/interface.go @@ -30,6 +30,8 @@ type ResolverName string // Requester is the interface implemented by a type that knows how to // submit requests for remote resources. +// +// Deprecated: Use [github.com/tektoncd/pipeline/pkg/remoteresolution/resource.Requester]. type Requester interface { // Submit accepts the name of a resolver to submit a request to // along with the request itself. @@ -41,6 +43,8 @@ type Requester interface { // type an opportunity to control properties such as whether the name of // a request has particular properties, whether the request should be made // to a specific namespace, and precisely which parameters should be included. +// +// Deprecated: Use [github.com/tektoncd/pipeline/pkg/remoteresolution/resource.Request]. type Request interface { Name() string Namespace() string diff --git a/pkg/resolution/resolver/bundle/resolver.go b/pkg/resolution/resolver/bundle/resolver.go index b23b2f7a959..9f88ff2caec 100644 --- a/pkg/resolution/resolver/bundle/resolver.go +++ b/pkg/resolution/resolver/bundle/resolver.go @@ -49,6 +49,8 @@ const ( ) // Resolver implements a framework.Resolver that can fetch files from OCI bundles. +// +// Deprecated: Use [github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/bundle.Resolver] instead. type Resolver struct { kubeClientSet kubernetes.Interface } diff --git a/pkg/resolution/resolver/cluster/resolver.go b/pkg/resolution/resolver/cluster/resolver.go index f3781cbef33..108babb7e31 100644 --- a/pkg/resolution/resolver/cluster/resolver.go +++ b/pkg/resolution/resolver/cluster/resolver.go @@ -51,6 +51,8 @@ const ( var _ framework.Resolver = &Resolver{} // Resolver implements a framework.Resolver that can fetch resources from other namespaces. +// +// Deprecated: Use [github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/cluster.Resolver] instead. type Resolver struct { pipelineClientSet clientset.Interface } diff --git a/pkg/resolution/resolver/framework/interface.go b/pkg/resolution/resolver/framework/interface.go index 33a9efab4d9..39e1fbfba06 100644 --- a/pkg/resolution/resolver/framework/interface.go +++ b/pkg/resolution/resolver/framework/interface.go @@ -26,6 +26,8 @@ import ( // Resolver is the interface to implement for type-specific resource // resolution. It fetches resources from a given type of remote location // and returns their content along with any associated annotations. +// +// Deprecated: Use [github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework.Resolver] instead. type Resolver interface { // Initialize is called at the moment the resolver controller is // instantiated and is a good place to setup things like diff --git a/pkg/resolution/resolver/framework/reconciler.go b/pkg/resolution/resolver/framework/reconciler.go index b981ea6e02a..4950a90c74d 100644 --- a/pkg/resolution/resolver/framework/reconciler.go +++ b/pkg/resolution/resolver/framework/reconciler.go @@ -43,6 +43,8 @@ import ( // Reconciler handles ResolutionRequest objects, performs functionality // common to all resolvers and delegates resolver-specific actions // to its embedded type-specific Resolver object. +// +// Deprecated: Use [github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework.Reconciler] instead. type Reconciler struct { // Implements reconciler.LeaderAware reconciler.LeaderAwareFuncs diff --git a/pkg/resolution/resolver/git/resolver.go b/pkg/resolution/resolver/git/resolver.go index c8294de862f..b0226e2bebc 100644 --- a/pkg/resolution/resolver/git/resolver.go +++ b/pkg/resolution/resolver/git/resolver.go @@ -73,6 +73,8 @@ const ( var _ framework.Resolver = &Resolver{} // Resolver implements a framework.Resolver that can fetch files from git. +// +// Deprecated: Use [github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/git.Resolver] instead. type Resolver struct { kubeClient kubernetes.Interface logger *zap.SugaredLogger diff --git a/pkg/resolution/resolver/http/resolver.go b/pkg/resolution/resolver/http/resolver.go index 1b9c9e7c921..88447f43ba1 100644 --- a/pkg/resolution/resolver/http/resolver.go +++ b/pkg/resolution/resolver/http/resolver.go @@ -59,6 +59,8 @@ const ( ) // Resolver implements a framework.Resolver that can fetch files from an HTTP URL +// +// Deprecated: Use [github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/http.Resolver] instead. type Resolver struct { kubeClient kubernetes.Interface logger *zap.SugaredLogger diff --git a/pkg/resolution/resolver/hub/resolver.go b/pkg/resolution/resolver/hub/resolver.go index a4f11726f99..db2d9d29413 100644 --- a/pkg/resolution/resolver/hub/resolver.go +++ b/pkg/resolution/resolver/hub/resolver.go @@ -46,6 +46,8 @@ const ( ) // Resolver implements a framework.Resolver that can fetch files from OCI bundles. +// +// Deprecated: Use [github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/hub.Resolver] instead. type Resolver struct { // TektonHubURL is the URL for hub resolver with type tekton TektonHubURL string diff --git a/pkg/resolution/resource/crd_resource.go b/pkg/resolution/resource/crd_resource.go index 39e41692075..9e1281a63a7 100644 --- a/pkg/resolution/resource/crd_resource.go +++ b/pkg/resolution/resource/crd_resource.go @@ -34,6 +34,8 @@ import ( // CRDRequester implements the Requester interface using // ResolutionRequest CRDs. +// +// Deprecated: Use [github.com/tektoncd/pipeline/pkg/remoteresolution/resource.CRDRequester] instead. type CRDRequester struct { clientset rrclient.Interface lister rrlisters.ResolutionRequestLister @@ -43,6 +45,8 @@ type CRDRequester struct { // ResolutionRequest CRD objects to mediate between the caller who wants a // resource (e.g. Tekton Pipelines) and the responder who can fetch // it (e.g. the gitresolver) +// +// Deprecated: Use [github.com/tektoncd/pipeline/pkg/remoteresolution/resource.NewCRDRequester] instead. func NewCRDRequester(clientset rrclient.Interface, lister rrlisters.ResolutionRequestLister) *CRDRequester { return &CRDRequester{clientset, lister} } diff --git a/pkg/resolution/resource/request.go b/pkg/resolution/resource/request.go index 792267ad36f..a3d8a967be5 100644 --- a/pkg/resolution/resource/request.go +++ b/pkg/resolution/resource/request.go @@ -21,6 +21,8 @@ import v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" var _ Request = &BasicRequest{} // BasicRequest holds the fields needed to submit a new resource request. +// +// Deprecated: Use [github.com/tektoncd/pipeline/pkg/remoteresolution/resource.BasicRequest] instead. type BasicRequest struct { name string namespace string @@ -29,6 +31,8 @@ type BasicRequest struct { // NewRequest returns an instance of a BasicRequest with the given name, // namespace and params. +// +// Deprecated: Use [github.com/tektoncd/pipeline/pkg/remoteresolution/resource.NewRequest] instead. func NewRequest(name, namespace string, params v1.Params) Request { return &BasicRequest{name, namespace, params} } From 3722bfe2612523c1966396fb922eb1ccbb64a6f5 Mon Sep 17 00:00:00 2001 From: seternate Date: Mon, 29 Apr 2024 09:09:41 +0200 Subject: [PATCH 10/23] Fix version mismatch of aws-sdk-go-v2 Fix version mismatch of github.com/aws/aws-sdk-go-v2 and github.com/aws/aws-sdk-go-v2/ecr due to a breaking change in aws-sdk-go-v2 of version v1.23.0. The mismatch is caused by the 2 dependencies github.com/sigstore/sigstore/pkg/signature/kms/aws and github.com/google/go-containerregistry using aws-sdk-go-v2 in v.18.x and v1.26.x. When no command or script was given to a Task, this caused the entrypoint resolve logic to fail with a "401 Not Authorized", when trying to get the manifest from a private AWS ECR. --- go.mod | 6 + go.sum | 8 +- .../aws-sdk-go-v2/service/ecr/CHANGELOG.md | 161 ++ .../aws-sdk-go-v2/service/ecr/api_client.go | 338 ++-- .../ecr/api_op_BatchCheckLayerAvailability.go | 38 +- .../service/ecr/api_op_BatchDeleteImage.go | 38 +- .../service/ecr/api_op_BatchGetImage.go | 38 +- ...BatchGetRepositoryScanningConfiguration.go | 38 +- .../service/ecr/api_op_CompleteLayerUpload.go | 38 +- .../ecr/api_op_CreatePullThroughCacheRule.go | 68 +- .../service/ecr/api_op_CreateRepository.go | 42 +- .../ecr/api_op_DeleteLifecyclePolicy.go | 38 +- .../ecr/api_op_DeletePullThroughCacheRule.go | 42 +- .../ecr/api_op_DeleteRegistryPolicy.go | 38 +- .../service/ecr/api_op_DeleteRepository.go | 46 +- .../ecr/api_op_DeleteRepositoryPolicy.go | 38 +- .../api_op_DescribeImageReplicationStatus.go | 38 +- .../ecr/api_op_DescribeImageScanFindings.go | 49 +- .../service/ecr/api_op_DescribeImages.go | 37 +- .../api_op_DescribePullThroughCacheRules.go | 37 +- .../service/ecr/api_op_DescribeRegistry.go | 38 +- .../ecr/api_op_DescribeRepositories.go | 37 +- .../ecr/api_op_GetAuthorizationToken.go | 38 +- .../ecr/api_op_GetDownloadUrlForLayer.go | 38 +- .../service/ecr/api_op_GetLifecyclePolicy.go | 38 +- .../ecr/api_op_GetLifecyclePolicyPreview.go | 49 +- .../service/ecr/api_op_GetRegistryPolicy.go | 38 +- ...api_op_GetRegistryScanningConfiguration.go | 38 +- .../service/ecr/api_op_GetRepositoryPolicy.go | 38 +- .../service/ecr/api_op_InitiateLayerUpload.go | 38 +- .../service/ecr/api_op_ListImages.go | 37 +- .../service/ecr/api_op_ListTagsForResource.go | 38 +- .../service/ecr/api_op_PutImage.go | 38 +- .../api_op_PutImageScanningConfiguration.go | 38 +- .../ecr/api_op_PutImageTagMutability.go | 38 +- .../service/ecr/api_op_PutLifecyclePolicy.go | 38 +- .../service/ecr/api_op_PutRegistryPolicy.go | 38 +- ...api_op_PutRegistryScanningConfiguration.go | 38 +- .../ecr/api_op_PutReplicationConfiguration.go | 38 +- .../service/ecr/api_op_SetRepositoryPolicy.go | 38 +- .../service/ecr/api_op_StartImageScan.go | 38 +- .../ecr/api_op_StartLifecyclePolicyPreview.go | 38 +- .../service/ecr/api_op_TagResource.go | 38 +- .../service/ecr/api_op_UntagResource.go | 38 +- .../ecr/api_op_UpdatePullThroughCacheRule.go | 158 ++ .../service/ecr/api_op_UploadLayerPart.go | 38 +- .../api_op_ValidatePullThroughCacheRule.go | 163 ++ .../aws/aws-sdk-go-v2/service/ecr/auth.go | 284 +++ .../service/ecr/deserializers.go | 1716 ++++++++++++----- .../aws-sdk-go-v2/service/ecr/endpoints.go | 416 +++- .../aws-sdk-go-v2/service/ecr/generated.json | 7 + .../service/ecr/go_module_metadata.go | 2 +- .../ecr/internal/endpoints/endpoints.go | 41 +- .../aws/aws-sdk-go-v2/service/ecr/options.go | 217 +++ .../aws-sdk-go-v2/service/ecr/serializers.go | 159 ++ .../aws-sdk-go-v2/service/ecr/types/enums.go | 32 + .../aws-sdk-go-v2/service/ecr/types/errors.go | 138 ++ .../aws-sdk-go-v2/service/ecr/types/types.go | 26 +- .../aws-sdk-go-v2/service/ecr/validators.go | 125 ++ .../service/ecrpublic/CHANGELOG.md | 150 ++ .../service/ecrpublic/api_client.go | 338 ++-- .../api_op_BatchCheckLayerAvailability.go | 38 +- .../ecrpublic/api_op_BatchDeleteImage.go | 38 +- .../ecrpublic/api_op_CompleteLayerUpload.go | 38 +- .../ecrpublic/api_op_CreateRepository.go | 38 +- .../ecrpublic/api_op_DeleteRepository.go | 38 +- .../api_op_DeleteRepositoryPolicy.go | 38 +- .../ecrpublic/api_op_DescribeImageTags.go | 37 +- .../ecrpublic/api_op_DescribeImages.go | 37 +- .../ecrpublic/api_op_DescribeRegistries.go | 37 +- .../ecrpublic/api_op_DescribeRepositories.go | 37 +- .../ecrpublic/api_op_GetAuthorizationToken.go | 38 +- .../api_op_GetRegistryCatalogData.go | 38 +- .../api_op_GetRepositoryCatalogData.go | 38 +- .../ecrpublic/api_op_GetRepositoryPolicy.go | 38 +- .../ecrpublic/api_op_InitiateLayerUpload.go | 38 +- .../ecrpublic/api_op_ListTagsForResource.go | 38 +- .../service/ecrpublic/api_op_PutImage.go | 38 +- .../api_op_PutRegistryCatalogData.go | 38 +- .../api_op_PutRepositoryCatalogData.go | 38 +- .../ecrpublic/api_op_SetRepositoryPolicy.go | 38 +- .../service/ecrpublic/api_op_TagResource.go | 38 +- .../service/ecrpublic/api_op_UntagResource.go | 38 +- .../ecrpublic/api_op_UploadLayerPart.go | 38 +- .../aws-sdk-go-v2/service/ecrpublic/auth.go | 284 +++ .../service/ecrpublic/deserializers.go | 351 ++-- .../service/ecrpublic/endpoints.go | 378 +++- .../service/ecrpublic/generated.json | 5 + .../service/ecrpublic/go_module_metadata.go | 2 +- .../ecrpublic/internal/endpoints/endpoints.go | 25 +- .../service/ecrpublic/options.go | 217 +++ vendor/modules.txt | 10 +- 92 files changed, 6400 insertions(+), 1849 deletions(-) create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UpdatePullThroughCacheRule.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ValidatePullThroughCacheRule.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ecr/auth.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ecr/options.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/auth.go create mode 100644 vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/options.go diff --git a/go.mod b/go.mod index 1594c6e439e..8997d908004 100644 --- a/go.mod +++ b/go.mod @@ -139,6 +139,12 @@ require ( gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect ) +// TODO: Remove this once github.com/google/go-containerregistry uses github.com/aws/aws-sdk-go-v2 >v1.23.0 +replace ( + github.com/aws/aws-sdk-go-v2/service/ecr => github.com/aws/aws-sdk-go-v2/service/ecr v1.27.3 + github.com/aws/aws-sdk-go-v2/service/ecrpublic => github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.23.3 +) + require ( cloud.google.com/go/compute v1.24.0 // indirect contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d // indirect diff --git a/go.sum b/go.sum index ecc5a543548..555f8379241 100644 --- a/go.sum +++ b/go.sum @@ -176,10 +176,10 @@ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 v2.6.4/go.mod h1:WjpDrhWisWOI github.com/aws/aws-sdk-go-v2/internal/ini v1.3.34/go.mod h1:Etz2dj6UHYuw+Xw830KfzCfWGMzqvUTCjUj5b76GVDc= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 h1:hT8rVHwugYE2lEfdFE0QWVo81lF7jMrYJVDWI+f+VxU= github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0/go.mod h1:8tu/lYfQfFe6IGnaOdrpVgEL2IrrDOf6/m9RQum4NkY= -github.com/aws/aws-sdk-go-v2/service/ecr v1.18.11 h1:wlTgmb/sCmVRJrN5De3CiHj4v/bTCgL5+qpdEd0CPtw= -github.com/aws/aws-sdk-go-v2/service/ecr v1.18.11/go.mod h1:Ce1q2jlNm8BVpjLaOnwnm5v2RClAbK6txwPljFzyW6c= -github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.16.2 h1:yflJrGmi1pXtP9lOpOeaNZyc0vXnJTuP2sor3nJcGGo= -github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.16.2/go.mod h1:uHtRE7aqXNmpeYL+7Ec7LacH5zC9+w2T5MBOeEKDdu0= +github.com/aws/aws-sdk-go-v2/service/ecr v1.27.3 h1:gfgt0D8MGL3gHrJPEv4rcWptA4Nz7uYn25ls8lLiANw= +github.com/aws/aws-sdk-go-v2/service/ecr v1.27.3/go.mod h1:O5Fvd41s5KfDG093xLM7FhGiH6EmhmEli5D5MQH3TWw= +github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.23.3 h1:gaq/4fd2/bQeJ33m4csgL7DJHrrmvGhqnrsxchNr46c= +github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.23.3/go.mod h1:vn+Rz9fAFGJtDXbBmYdTc71Q8iF/W/uK1/ec93hinD8= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1 h1:EyBZibRTVAs6ECHZOw5/wlylS9OcTzwyjeQMudmREjE= github.com/aws/aws-sdk-go-v2/service/internal/accept-encoding v1.11.1/go.mod h1:JKpmtYhhPs7D97NL/ltqz7yCkERFW5dOlHyVl66ZYF8= github.com/aws/aws-sdk-go-v2/service/internal/presigned-url v1.9.27/go.mod h1:EOwBD4J4S5qYszS5/3DpkejfuK+Z5/1uzICfPaZLtqw= diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/CHANGELOG.md index 3d155118e33..53164b65bde 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/CHANGELOG.md @@ -1,3 +1,164 @@ +# v1.27.3 (2024-03-18) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.27.2 (2024-03-07) + +* **Bug Fix**: Remove dependency on go-cmp. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.27.1 (2024-02-23) + +* **Bug Fix**: Move all common, SDK-side middleware stack ops into the service client module to prevent cross-module compatibility issues in the future. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.27.0 (2024-02-22) + +* **Feature**: Add middleware stack snapshot tests. + +# v1.26.2 (2024-02-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.26.1 (2024-02-20) + +* **Bug Fix**: When sourcing values for a service's `EndpointParameters`, the lack of a configured region (i.e. `options.Region == ""`) will now translate to a `nil` value for `EndpointParameters.Region` instead of a pointer to the empty string `""`. This will result in a much more explicit error when calling an operation instead of an obscure hostname lookup failure. + +# v1.26.0 (2024-02-16) + +* **Feature**: Add new ClientOptions field to waiter config which allows you to extend the config for operation calls made by waiters. + +# v1.25.1 (2024-02-15) + +* **Bug Fix**: Correct failure to determine the error type in awsJson services that could occur when errors were modeled with a non-string `code` field. + +# v1.25.0 (2024-02-13) + +* **Feature**: Bump minimum Go version to 1.20 per our language support policy. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.24.7 (2024-01-04) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.24.6 (2023-12-20) + +* No change notes available for this release. + +# v1.24.5 (2023-12-08) + +* **Bug Fix**: Reinstate presence of default Retryer in functional options, but still respect max attempts set therein. + +# v1.24.4 (2023-12-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.24.3 (2023-12-06) + +* **Bug Fix**: Restore pre-refactor auth behavior where all operations could technically be performed anonymously. + +# v1.24.2 (2023-12-01) + +* **Bug Fix**: Correct wrapping of errors in authentication workflow. +* **Bug Fix**: Correctly recognize cache-wrapped instances of AnonymousCredentials at client construction. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.24.1 (2023-11-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.24.0 (2023-11-29) + +* **Feature**: Expose Options() accessor on service clients. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.23.3 (2023-11-28.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.23.2 (2023-11-28) + +* **Bug Fix**: Respect setting RetryMaxAttempts in functional options at client construction. + +# v1.23.1 (2023-11-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.23.0 (2023-11-17) + +* **Feature**: Documentation and operational updates for Amazon ECR, adding support for pull through cache rules for upstream registries that require authentication. + +# v1.22.2 (2023-11-15) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.22.1 (2023-11-09) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.22.0 (2023-11-01) + +* **Feature**: Adds support for configured endpoints via environment variables and the AWS shared configuration file. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.21.0 (2023-10-31) + +* **Feature**: **BREAKING CHANGE**: Bump minimum go version to 1.19 per the revised [go version support policy](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-aligns-with-go-release-policy-on-supported-runtimes/). +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.20.2 (2023-10-12) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.20.1 (2023-10-06) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.20.0 (2023-09-11) + +* **Feature**: This release will have ValidationException be thrown from ECR LifecyclePolicy APIs in regions LifecyclePolicy is not supported, this includes existing Amazon Dedicated Cloud (ADC) regions. This release will also change Tag: TagValue and Tag: TagKey to required. + +# v1.19.5 (2023-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.4 (2023-08-18) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.3 (2023-08-17) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.2 (2023-08-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.1 (2023-08-01) + +* No change notes available for this release. + +# v1.19.0 (2023-07-31) + +* **Feature**: Adds support for smithy-modeled endpoint resolution. A new rules-based endpoint resolution will be added to the SDK which will supercede and deprecate existing endpoint resolution. Specifically, EndpointResolver will be deprecated while BaseEndpoint and EndpointResolverV2 will take its place. For more information, please see the Endpoints section in our Developer Guide. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.15 (2023-07-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.14 (2023-07-13) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.13 (2023-06-15) + +* No change notes available for this release. + +# v1.18.12 (2023-06-13) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.18.11 (2023-05-04) * No change notes available for this release. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_client.go index add37d360a5..9d8a1588aa0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_client.go @@ -4,12 +4,15 @@ package ecr import ( "context" + "fmt" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/aws/defaults" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" "github.com/aws/aws-sdk-go-v2/aws/retry" "github.com/aws/aws-sdk-go-v2/aws/signer/v4" awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" smithy "github.com/aws/smithy-go" smithydocument "github.com/aws/smithy-go/document" @@ -46,128 +49,48 @@ func New(options Options, optFns ...func(*Options)) *Client { resolveHTTPSignerV4(&options) - resolveDefaultEndpointConfiguration(&options) + resolveEndpointResolverV2(&options) + + resolveAuthSchemeResolver(&options) for _, fn := range optFns { fn(&options) } - client := &Client{ - options: options, - } - - return client -} - -type Options struct { - // Set of options to modify how an operation is invoked. These apply to all - // operations invoked for this client. Use functional options on operation call to - // modify this list for per operation behavior. - APIOptions []func(*middleware.Stack) error - - // Configures the events that will be sent to the configured logger. - ClientLogMode aws.ClientLogMode - - // The credentials object to use when signing requests. - Credentials aws.CredentialsProvider - - // The configuration DefaultsMode that the SDK should use when constructing the - // clients initial default settings. - DefaultsMode aws.DefaultsMode - - // The endpoint options to be used when attempting to resolve an endpoint. - EndpointOptions EndpointResolverOptions - - // The service endpoint resolver. - EndpointResolver EndpointResolver - - // Signature Version 4 (SigV4) Signer - HTTPSignerV4 HTTPSignerV4 - - // The logger writer interface to write logging messages to. - Logger logging.Logger + finalizeRetryMaxAttempts(&options) - // The region to send requests to. (Required) - Region string + ignoreAnonymousAuth(&options) - // RetryMaxAttempts specifies the maximum number attempts an API client will call - // an operation that fails with a retryable error. A value of 0 is ignored, and - // will not be used to configure the API client created default retryer, or modify - // per operation call's retry max attempts. When creating a new API Clients this - // member will only be used if the Retryer Options member is nil. This value will - // be ignored if Retryer is not nil. If specified in an operation call's functional - // options with a value that is different than the constructed client's Options, - // the Client's Retryer will be wrapped to use the operation's specific - // RetryMaxAttempts value. - RetryMaxAttempts int + wrapWithAnonymousAuth(&options) - // RetryMode specifies the retry mode the API client will be created with, if - // Retryer option is not also specified. When creating a new API Clients this - // member will only be used if the Retryer Options member is nil. This value will - // be ignored if Retryer is not nil. Currently does not support per operation call - // overrides, may in the future. - RetryMode aws.RetryMode + resolveAuthSchemes(&options) - // Retryer guides how HTTP requests should be retried in case of recoverable - // failures. When nil the API client will use a default retryer. The kind of - // default retry created by the API client can be changed with the RetryMode - // option. - Retryer aws.Retryer - - // The RuntimeEnvironment configuration, only populated if the DefaultsMode is set - // to DefaultsModeAuto and is initialized using config.LoadDefaultConfig . You - // should not populate this structure programmatically, or rely on the values here - // within your applications. - RuntimeEnvironment aws.RuntimeEnvironment - - // The initial DefaultsMode used when the client options were constructed. If the - // DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved - // value was at that point in time. Currently does not support per operation call - // overrides, may in the future. - resolvedDefaultsMode aws.DefaultsMode - - // The HTTP client to invoke API calls with. Defaults to client's default HTTP - // implementation if nil. - HTTPClient HTTPClient -} - -// WithAPIOptions returns a functional option for setting the Client's APIOptions -// option. -func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { - return func(o *Options) { - o.APIOptions = append(o.APIOptions, optFns...) + client := &Client{ + options: options, } -} -// WithEndpointResolver returns a functional option for setting the Client's -// EndpointResolver option. -func WithEndpointResolver(v EndpointResolver) func(*Options) { - return func(o *Options) { - o.EndpointResolver = v - } + return client } -type HTTPClient interface { - Do(*http.Request) (*http.Response, error) +// Options returns a copy of the client configuration. +// +// Callers SHOULD NOT perform mutations on any inner structures within client +// config. Config overrides should instead be made on a per-operation basis through +// functional options. +func (c *Client) Options() Options { + return c.options.Copy() } -// Copy creates a clone where the APIOptions list is deep copied. -func (o Options) Copy() Options { - to := o - to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) - copy(to.APIOptions, o.APIOptions) - - return to -} func (c *Client) invokeOperation(ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error) (result interface{}, metadata middleware.Metadata, err error) { ctx = middleware.ClearStackValues(ctx) stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) options := c.options.Copy() + for _, fn := range optFns { fn(&options) } - finalizeRetryMaxAttemptOptions(&options, *c) + finalizeOperationRetryMaxAttempts(&options, *c) finalizeClientEndpointResolverOptions(&options) @@ -195,8 +118,89 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf return result, metadata, err } +type operationInputKey struct{} + +func setOperationInput(ctx context.Context, input interface{}) context.Context { + return middleware.WithStackValue(ctx, operationInputKey{}, input) +} + +func getOperationInput(ctx context.Context) interface{} { + return middleware.GetStackValue(ctx, operationInputKey{}) +} + +type setOperationInputMiddleware struct { +} + +func (*setOperationInputMiddleware) ID() string { + return "setOperationInput" +} + +func (m *setOperationInputMiddleware) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + ctx = setOperationInput(ctx, in.Parameters) + return next.HandleSerialize(ctx, in) +} + +func addProtocolFinalizerMiddlewares(stack *middleware.Stack, options Options, operation string) error { + if err := stack.Finalize.Add(&resolveAuthSchemeMiddleware{operation: operation, options: options}, middleware.Before); err != nil { + return fmt.Errorf("add ResolveAuthScheme: %w", err) + } + if err := stack.Finalize.Insert(&getIdentityMiddleware{options: options}, "ResolveAuthScheme", middleware.After); err != nil { + return fmt.Errorf("add GetIdentity: %v", err) + } + if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", middleware.After); err != nil { + return fmt.Errorf("add ResolveEndpointV2: %v", err) + } + if err := stack.Finalize.Insert(&signRequestMiddleware{}, "ResolveEndpointV2", middleware.After); err != nil { + return fmt.Errorf("add Signing: %w", err) + } + return nil +} +func resolveAuthSchemeResolver(options *Options) { + if options.AuthSchemeResolver == nil { + options.AuthSchemeResolver = &defaultAuthSchemeResolver{} + } +} + +func resolveAuthSchemes(options *Options) { + if options.AuthSchemes == nil { + options.AuthSchemes = []smithyhttp.AuthScheme{ + internalauth.NewHTTPAuthScheme("aws.auth#sigv4", &internalauthsmithy.V4SignerAdapter{ + Signer: options.HTTPSignerV4, + Logger: options.Logger, + LogSigning: options.ClientLogMode.IsSigning(), + }), + } + } +} + type noSmithyDocumentSerde = smithydocument.NoSerde +type legacyEndpointContextSetter struct { + LegacyResolver EndpointResolver +} + +func (*legacyEndpointContextSetter) ID() string { + return "legacyEndpointContextSetter" +} + +func (m *legacyEndpointContextSetter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, +) { + if m.LegacyResolver != nil { + ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) + } + + return next.HandleInitialize(ctx, in) + +} +func addlegacyEndpointContextSetter(stack *middleware.Stack, o Options) error { + return stack.Initialize.Add(&legacyEndpointContextSetter{ + LegacyResolver: o.EndpointResolver, + }, middleware.Before) +} + func resolveDefaultLogger(o *Options) { if o.Logger != nil { return @@ -234,6 +238,7 @@ func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { APIOptions: cfg.APIOptions, Logger: cfg.Logger, ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) @@ -241,6 +246,7 @@ func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { resolveAWSEndpointResolver(cfg, &opts) resolveUseDualStackEndpoint(cfg, &opts) resolveUseFIPSEndpoint(cfg, &opts) + resolveBaseEndpoint(cfg, &opts) return New(opts, optFns...) } @@ -332,7 +338,15 @@ func resolveAWSRetryMaxAttempts(cfg aws.Config, o *Options) { o.RetryMaxAttempts = cfg.RetryMaxAttempts } -func finalizeRetryMaxAttemptOptions(o *Options, client Client) { +func finalizeRetryMaxAttempts(o *Options) { + if o.RetryMaxAttempts == 0 { + return + } + + o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts) +} + +func finalizeOperationRetryMaxAttempts(o *Options, client Client) { if v := o.RetryMaxAttempts; v == 0 || v == client.options.RetryMaxAttempts { return } @@ -344,20 +358,39 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil { return } - o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions, NewDefaultEndpointResolver()) + o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) } -func addClientUserAgent(stack *middleware.Stack) error { - return awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "ecr", goModuleVersion)(stack) +func addClientUserAgent(stack *middleware.Stack, options Options) error { + ua, err := getOrAddRequestUserAgent(stack) + if err != nil { + return err + } + + ua.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "ecr", goModuleVersion) + if len(options.AppID) > 0 { + ua.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID) + } + + return nil } -func addHTTPSignerV4Middleware(stack *middleware.Stack, o Options) error { - mw := v4.NewSignHTTPRequestMiddleware(v4.SignHTTPRequestMiddlewareOptions{ - CredentialsProvider: o.Credentials, - Signer: o.HTTPSignerV4, - LogSigning: o.ClientLogMode.IsSigning(), - }) - return stack.Finalize.Add(mw, middleware.After) +func getOrAddRequestUserAgent(stack *middleware.Stack) (*awsmiddleware.RequestUserAgent, error) { + id := (*awsmiddleware.RequestUserAgent)(nil).ID() + mw, ok := stack.Build.Get(id) + if !ok { + mw = awsmiddleware.NewRequestUserAgent() + if err := stack.Build.Add(mw, middleware.After); err != nil { + return nil, err + } + } + + ua, ok := mw.(*awsmiddleware.RequestUserAgent) + if !ok { + return nil, fmt.Errorf("%T for %s middleware did not match expected type", mw, id) + } + + return ua, nil } type HTTPSignerV4 interface { @@ -378,12 +411,48 @@ func newDefaultV4Signer(o Options) *v4.Signer { }) } -func addRetryMiddlewares(stack *middleware.Stack, o Options) error { - mo := retry.AddRetryMiddlewaresOptions{ - Retryer: o.Retryer, - LogRetryAttempts: o.ClientLogMode.IsRetries(), +func addClientRequestID(stack *middleware.Stack) error { + return stack.Build.Add(&awsmiddleware.ClientRequestID{}, middleware.After) +} + +func addComputeContentLength(stack *middleware.Stack) error { + return stack.Build.Add(&smithyhttp.ComputeContentLength{}, middleware.After) +} + +func addRawResponseToMetadata(stack *middleware.Stack) error { + return stack.Deserialize.Add(&awsmiddleware.AddRawResponse{}, middleware.Before) +} + +func addRecordResponseTiming(stack *middleware.Stack) error { + return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After) +} +func addStreamingEventsPayload(stack *middleware.Stack) error { + return stack.Finalize.Add(&v4.StreamingEventsPayload{}, middleware.Before) +} + +func addUnsignedPayload(stack *middleware.Stack) error { + return stack.Finalize.Insert(&v4.UnsignedPayload{}, "ResolveEndpointV2", middleware.After) +} + +func addComputePayloadSHA256(stack *middleware.Stack) error { + return stack.Finalize.Insert(&v4.ComputePayloadSHA256{}, "ResolveEndpointV2", middleware.After) +} + +func addContentSHA256Header(stack *middleware.Stack) error { + return stack.Finalize.Insert(&v4.ContentSHA256Header{}, (*v4.ComputePayloadSHA256)(nil).ID(), middleware.After) +} + +func addRetry(stack *middleware.Stack, o Options) error { + attempt := retry.NewAttemptMiddleware(o.Retryer, smithyhttp.RequestCloner, func(m *retry.Attempt) { + m.LogAttempts = o.ClientLogMode.IsRetries() + }) + if err := stack.Finalize.Insert(attempt, "Signing", middleware.Before); err != nil { + return err + } + if err := stack.Finalize.Insert(&retry.MetricsHeader{}, attempt.ID(), middleware.After); err != nil { + return err } - return retry.AddRetryMiddlewares(stack, mo) + return nil } // resolves dual-stack endpoint configuration @@ -416,12 +485,18 @@ func resolveUseFIPSEndpoint(cfg aws.Config, o *Options) error { return nil } +func addRecursionDetection(stack *middleware.Stack) error { + return stack.Build.Add(&awsmiddleware.RecursionDetection{}, middleware.After) +} + func addRequestIDRetrieverMiddleware(stack *middleware.Stack) error { - return awsmiddleware.AddRequestIDRetrieverMiddleware(stack) + return stack.Deserialize.Insert(&awsmiddleware.RequestIDRetriever{}, "OperationDeserializer", middleware.Before) + } func addResponseErrorMiddleware(stack *middleware.Stack) error { - return awshttp.AddResponseErrorMiddleware(stack) + return stack.Deserialize.Insert(&awshttp.ResponseErrorWrapper{}, "RequestIDRetriever", middleware.Before) + } func addRequestResponseLogging(stack *middleware.Stack, o Options) error { @@ -432,3 +507,32 @@ func addRequestResponseLogging(stack *middleware.Stack, o Options) error { LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), }, middleware.After) } + +type disableHTTPSMiddleware struct { + DisableHTTPS bool +} + +func (*disableHTTPSMiddleware) ID() string { + return "disableHTTPS" +} + +func (m *disableHTTPSMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + req, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.DisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) { + req.URL.Scheme = "http" + } + + return next.HandleFinalize(ctx, in) +} + +func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { + return stack.Finalize.Insert(&disableHTTPSMiddleware{ + DisableHTTPS: o.EndpointOptions.DisableHTTPS, + }, "ResolveEndpointV2", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchCheckLayerAvailability.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchCheckLayerAvailability.go index 13489da617f..a3c278bc982 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchCheckLayerAvailability.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchCheckLayerAvailability.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -68,6 +68,9 @@ type BatchCheckLayerAvailabilityOutput struct { } func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpBatchCheckLayerAvailability{}, middleware.After) if err != nil { return err @@ -76,34 +79,38 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "BatchCheckLayerAvailability"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -112,13 +119,16 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpBatchCheckLayerAvailabilityValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opBatchCheckLayerAvailability(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -130,6 +140,9 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -137,7 +150,6 @@ func newServiceMetadataMiddleware_opBatchCheckLayerAvailability(region string) * return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "BatchCheckLayerAvailability", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchDeleteImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchDeleteImage.go index 646f46a0048..d9846d25858 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchDeleteImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchDeleteImage.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -69,6 +69,9 @@ type BatchDeleteImageOutput struct { } func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpBatchDeleteImage{}, middleware.After) if err != nil { return err @@ -77,34 +80,38 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "BatchDeleteImage"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -113,13 +120,16 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpBatchDeleteImageValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opBatchDeleteImage(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -131,6 +141,9 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -138,7 +151,6 @@ func newServiceMetadataMiddleware_opBatchDeleteImage(region string) *awsmiddlewa return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "BatchDeleteImage", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetImage.go index ce9b83a3c15..756873b39fc 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetImage.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -71,6 +71,9 @@ type BatchGetImageOutput struct { } func (c *Client) addOperationBatchGetImageMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpBatchGetImage{}, middleware.After) if err != nil { return err @@ -79,34 +82,38 @@ func (c *Client) addOperationBatchGetImageMiddlewares(stack *middleware.Stack, o if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "BatchGetImage"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -115,13 +122,16 @@ func (c *Client) addOperationBatchGetImageMiddlewares(stack *middleware.Stack, o if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpBatchGetImageValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opBatchGetImage(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -133,6 +143,9 @@ func (c *Client) addOperationBatchGetImageMiddlewares(stack *middleware.Stack, o if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -140,7 +153,6 @@ func newServiceMetadataMiddleware_opBatchGetImage(region string) *awsmiddleware. return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "BatchGetImage", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetRepositoryScanningConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetRepositoryScanningConfiguration.go index 3611dbe55ed..4d2a19bb230 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetRepositoryScanningConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_BatchGetRepositoryScanningConfiguration.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -52,6 +52,9 @@ type BatchGetRepositoryScanningConfigurationOutput struct { } func (c *Client) addOperationBatchGetRepositoryScanningConfigurationMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpBatchGetRepositoryScanningConfiguration{}, middleware.After) if err != nil { return err @@ -60,34 +63,38 @@ func (c *Client) addOperationBatchGetRepositoryScanningConfigurationMiddlewares( if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "BatchGetRepositoryScanningConfiguration"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -96,13 +103,16 @@ func (c *Client) addOperationBatchGetRepositoryScanningConfigurationMiddlewares( if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpBatchGetRepositoryScanningConfigurationValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opBatchGetRepositoryScanningConfiguration(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -114,6 +124,9 @@ func (c *Client) addOperationBatchGetRepositoryScanningConfigurationMiddlewares( if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -121,7 +134,6 @@ func newServiceMetadataMiddleware_opBatchGetRepositoryScanningConfiguration(regi return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "BatchGetRepositoryScanningConfiguration", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CompleteLayerUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CompleteLayerUpload.go index de6185b950f..a145f4d5a67 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CompleteLayerUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CompleteLayerUpload.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -79,6 +79,9 @@ type CompleteLayerUploadOutput struct { } func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpCompleteLayerUpload{}, middleware.After) if err != nil { return err @@ -87,34 +90,38 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "CompleteLayerUpload"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -123,13 +130,16 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpCompleteLayerUploadValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCompleteLayerUpload(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -141,6 +151,9 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -148,7 +161,6 @@ func newServiceMetadataMiddleware_opCompleteLayerUpload(region string) *awsmiddl return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "CompleteLayerUpload", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreatePullThroughCacheRule.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreatePullThroughCacheRule.go index 75c3ee4e719..8e0f2f8de6a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreatePullThroughCacheRule.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreatePullThroughCacheRule.go @@ -4,16 +4,18 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" + "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "time" ) // Creates a pull through cache rule. A pull through cache rule provides a way to -// cache images from an external public registry in your Amazon ECR private -// registry. +// cache images from an upstream registry source in your Amazon ECR private +// registry. For more information, see Using pull through cache rules (https://docs.aws.amazon.com/AmazonECR/latest/userguide/pull-through-cache.html) +// in the Amazon Elastic Container Registry User Guide. func (c *Client) CreatePullThroughCacheRule(ctx context.Context, params *CreatePullThroughCacheRuleInput, optFns ...func(*Options)) (*CreatePullThroughCacheRuleOutput, error) { if params == nil { params = &CreatePullThroughCacheRuleInput{} @@ -37,16 +39,31 @@ type CreatePullThroughCacheRuleInput struct { EcrRepositoryPrefix *string // The registry URL of the upstream public registry to use as the source for the - // pull through cache rule. + // pull through cache rule. The following is the syntax to use for each supported + // upstream registry. + // - Amazon ECR Public ( ecr-public ) - public.ecr.aws + // - Docker Hub ( docker-hub ) - registry-1.docker.io + // - Quay ( quay ) - quay.io + // - Kubernetes ( k8s ) - registry.k8s.io + // - GitHub Container Registry ( github-container-registry ) - ghcr.io + // - Microsoft Azure Container Registry ( azure-container-registry ) - + // .azurecr.io // // This member is required. UpstreamRegistryUrl *string + // The Amazon Resource Name (ARN) of the Amazon Web Services Secrets Manager + // secret that identifies the credentials to authenticate to the upstream registry. + CredentialArn *string + // The Amazon Web Services account ID associated with the registry to create the // pull through cache rule for. If you do not specify a registry, the default // registry is assumed. RegistryId *string + // The name of the upstream registry. + UpstreamRegistry types.UpstreamRegistry + noSmithyDocumentSerde } @@ -56,12 +73,19 @@ type CreatePullThroughCacheRuleOutput struct { // was created. CreatedAt *time.Time + // The Amazon Resource Name (ARN) of the Amazon Web Services Secrets Manager + // secret associated with the pull through cache rule. + CredentialArn *string + // The Amazon ECR repository prefix associated with the pull through cache rule. EcrRepositoryPrefix *string // The registry ID associated with the request. RegistryId *string + // The name of the upstream registry associated with the pull through cache rule. + UpstreamRegistry types.UpstreamRegistry + // The upstream registry URL associated with the pull through cache rule. UpstreamRegistryUrl *string @@ -72,6 +96,9 @@ type CreatePullThroughCacheRuleOutput struct { } func (c *Client) addOperationCreatePullThroughCacheRuleMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpCreatePullThroughCacheRule{}, middleware.After) if err != nil { return err @@ -80,34 +107,38 @@ func (c *Client) addOperationCreatePullThroughCacheRuleMiddlewares(stack *middle if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "CreatePullThroughCacheRule"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -116,13 +147,16 @@ func (c *Client) addOperationCreatePullThroughCacheRuleMiddlewares(stack *middle if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpCreatePullThroughCacheRuleValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreatePullThroughCacheRule(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -134,6 +168,9 @@ func (c *Client) addOperationCreatePullThroughCacheRuleMiddlewares(stack *middle if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -141,7 +178,6 @@ func newServiceMetadataMiddleware_opCreatePullThroughCacheRule(region string) *a return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "CreatePullThroughCacheRule", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepository.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepository.go index 362fe54b605..87088e1dd89 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepository.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_CreateRepository.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -32,7 +32,9 @@ type CreateRepositoryInput struct { // The name to use for the repository. The repository name may be specified on its // own (such as nginx-web-app ) or it can be prepended with a namespace to group - // the repository into a category (such as project-a/nginx-web-app ). + // the repository into a category (such as project-a/nginx-web-app ). The + // repository name must start with a letter and can only contain lowercase letters, + // numbers, hyphens, underscores, and forward slashes. // // This member is required. RepositoryName *string @@ -77,6 +79,9 @@ type CreateRepositoryOutput struct { } func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpCreateRepository{}, middleware.After) if err != nil { return err @@ -85,34 +90,38 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "CreateRepository"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -121,13 +130,16 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpCreateRepositoryValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateRepository(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -139,6 +151,9 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -146,7 +161,6 @@ func newServiceMetadataMiddleware_opCreateRepository(region string) *awsmiddlewa return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "CreateRepository", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteLifecyclePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteLifecyclePolicy.go index 914a512cd46..0b5887326ba 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteLifecyclePolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteLifecyclePolicy.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "time" @@ -63,6 +63,9 @@ type DeleteLifecyclePolicyOutput struct { } func (c *Client) addOperationDeleteLifecyclePolicyMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteLifecyclePolicy{}, middleware.After) if err != nil { return err @@ -71,34 +74,38 @@ func (c *Client) addOperationDeleteLifecyclePolicyMiddlewares(stack *middleware. if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteLifecyclePolicy"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -107,13 +114,16 @@ func (c *Client) addOperationDeleteLifecyclePolicyMiddlewares(stack *middleware. if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpDeleteLifecyclePolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteLifecyclePolicy(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -125,6 +135,9 @@ func (c *Client) addOperationDeleteLifecyclePolicyMiddlewares(stack *middleware. if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -132,7 +145,6 @@ func newServiceMetadataMiddleware_opDeleteLifecyclePolicy(region string) *awsmid return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "DeleteLifecyclePolicy", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeletePullThroughCacheRule.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeletePullThroughCacheRule.go index 413c55a2705..3340af4fdc7 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeletePullThroughCacheRule.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeletePullThroughCacheRule.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "time" @@ -48,6 +48,10 @@ type DeletePullThroughCacheRuleOutput struct { // The timestamp associated with the pull through cache rule. CreatedAt *time.Time + // The Amazon Resource Name (ARN) of the Amazon Web Services Secrets Manager + // secret associated with the pull through cache rule. + CredentialArn *string + // The Amazon ECR repository prefix associated with the request. EcrRepositoryPrefix *string @@ -64,6 +68,9 @@ type DeletePullThroughCacheRuleOutput struct { } func (c *Client) addOperationDeletePullThroughCacheRuleMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeletePullThroughCacheRule{}, middleware.After) if err != nil { return err @@ -72,34 +79,38 @@ func (c *Client) addOperationDeletePullThroughCacheRuleMiddlewares(stack *middle if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DeletePullThroughCacheRule"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -108,13 +119,16 @@ func (c *Client) addOperationDeletePullThroughCacheRuleMiddlewares(stack *middle if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpDeletePullThroughCacheRuleValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeletePullThroughCacheRule(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -126,6 +140,9 @@ func (c *Client) addOperationDeletePullThroughCacheRuleMiddlewares(stack *middle if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -133,7 +150,6 @@ func newServiceMetadataMiddleware_opDeletePullThroughCacheRule(region string) *a return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "DeletePullThroughCacheRule", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRegistryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRegistryPolicy.go index dceab652b1b..723b0f7fe86 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRegistryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRegistryPolicy.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -45,6 +45,9 @@ type DeleteRegistryPolicyOutput struct { } func (c *Client) addOperationDeleteRegistryPolicyMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteRegistryPolicy{}, middleware.After) if err != nil { return err @@ -53,34 +56,38 @@ func (c *Client) addOperationDeleteRegistryPolicyMiddlewares(stack *middleware.S if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteRegistryPolicy"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -89,10 +96,13 @@ func (c *Client) addOperationDeleteRegistryPolicyMiddlewares(stack *middleware.S if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteRegistryPolicy(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -104,6 +114,9 @@ func (c *Client) addOperationDeleteRegistryPolicyMiddlewares(stack *middleware.S if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -111,7 +124,6 @@ func newServiceMetadataMiddleware_opDeleteRegistryPolicy(region string) *awsmidd return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "DeleteRegistryPolicy", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepository.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepository.go index 0b2b866ce37..aba90863379 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepository.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepository.go @@ -4,15 +4,16 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) -// Deletes a repository. If the repository contains images, you must either delete -// all images in the repository or use the force option to delete the repository. +// Deletes a repository. If the repository isn't empty, you must either delete the +// contents of the repository or use the force option to delete the repository and +// have Amazon ECR delete all of its contents on your behalf. func (c *Client) DeleteRepository(ctx context.Context, params *DeleteRepositoryInput, optFns ...func(*Options)) (*DeleteRepositoryOutput, error) { if params == nil { params = &DeleteRepositoryInput{} @@ -35,7 +36,8 @@ type DeleteRepositoryInput struct { // This member is required. RepositoryName *string - // If a repository contains images, forces the deletion. + // If true, deleting the repository force deletes the contents of the repository. + // If false, the repository must be empty before attempting to delete it. Force bool // The Amazon Web Services account ID associated with the registry that contains @@ -58,6 +60,9 @@ type DeleteRepositoryOutput struct { } func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteRepository{}, middleware.After) if err != nil { return err @@ -66,34 +71,38 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteRepository"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -102,13 +111,16 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpDeleteRepositoryValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteRepository(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -120,6 +132,9 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -127,7 +142,6 @@ func newServiceMetadataMiddleware_opDeleteRepository(region string) *awsmiddlewa return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "DeleteRepository", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryPolicy.go index 593901b8eb0..9ebd8906160 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DeleteRepositoryPolicy.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -60,6 +60,9 @@ type DeleteRepositoryPolicyOutput struct { } func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteRepositoryPolicy{}, middleware.After) if err != nil { return err @@ -68,34 +71,38 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteRepositoryPolicy"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -104,13 +111,16 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpDeleteRepositoryPolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteRepositoryPolicy(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -122,6 +132,9 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -129,7 +142,6 @@ func newServiceMetadataMiddleware_opDeleteRepositoryPolicy(region string) *awsmi return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "DeleteRepositoryPolicy", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageReplicationStatus.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageReplicationStatus.go index 0085efcf27c..58b518cf2f4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageReplicationStatus.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageReplicationStatus.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -64,6 +64,9 @@ type DescribeImageReplicationStatusOutput struct { } func (c *Client) addOperationDescribeImageReplicationStatusMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeImageReplicationStatus{}, middleware.After) if err != nil { return err @@ -72,34 +75,38 @@ func (c *Client) addOperationDescribeImageReplicationStatusMiddlewares(stack *mi if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeImageReplicationStatus"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -108,13 +115,16 @@ func (c *Client) addOperationDescribeImageReplicationStatusMiddlewares(stack *mi if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpDescribeImageReplicationStatusValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeImageReplicationStatus(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -126,6 +136,9 @@ func (c *Client) addOperationDescribeImageReplicationStatusMiddlewares(stack *mi if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -133,7 +146,6 @@ func newServiceMetadataMiddleware_opDescribeImageReplicationStatus(region string return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "DescribeImageReplicationStatus", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageScanFindings.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageScanFindings.go index f75246f03fb..1947caec398 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageScanFindings.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImageScanFindings.go @@ -6,7 +6,6 @@ import ( "context" "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithytime "github.com/aws/smithy-go/time" @@ -99,6 +98,9 @@ type DescribeImageScanFindingsOutput struct { } func (c *Client) addOperationDescribeImageScanFindingsMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeImageScanFindings{}, middleware.After) if err != nil { return err @@ -107,34 +109,38 @@ func (c *Client) addOperationDescribeImageScanFindingsMiddlewares(stack *middlew if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeImageScanFindings"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -143,13 +149,16 @@ func (c *Client) addOperationDescribeImageScanFindingsMiddlewares(stack *middlew if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpDescribeImageScanFindingsValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeImageScanFindings(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -161,6 +170,9 @@ func (c *Client) addOperationDescribeImageScanFindingsMiddlewares(stack *middlew if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -269,8 +281,17 @@ type ImageScanCompleteWaiterOptions struct { // Set of options to modify how an operation is invoked. These apply to all // operations invoked for this client. Use functional options on operation call to // modify this list for per operation behavior. + // + // Passing options here is functionally equivalent to passing values to this + // config's ClientOptions field that extend the inner client's APIOptions directly. APIOptions []func(*middleware.Stack) error + // Functional options to be passed to all operations invoked by this client. + // + // Function values that modify the inner APIOptions are applied after the waiter + // config's own APIOptions modifiers. + ClientOptions []func(*Options) + // MinDelay is the minimum amount of time to delay between retries. If unset, // ImageScanCompleteWaiter will use default minimum delay of 5 seconds. Note that // MinDelay must resolve to a value lesser than or equal to the MaxDelay. @@ -369,6 +390,9 @@ func (w *ImageScanCompleteWaiter) WaitForOutput(ctx context.Context, params *Des out, err := w.client.DescribeImageScanFindings(ctx, params, func(o *Options) { o.APIOptions = append(o.APIOptions, apiOptions...) + for _, opt := range options.ClientOptions { + opt(o) + } }) retryable, err := options.Retryable(ctx, params, out, err) @@ -444,7 +468,6 @@ func newServiceMetadataMiddleware_opDescribeImageScanFindings(region string) *aw return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "DescribeImageScanFindings", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImages.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImages.go index dd8e354bc26..70894b9e57e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImages.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeImages.go @@ -6,7 +6,6 @@ import ( "context" "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -88,6 +87,9 @@ type DescribeImagesOutput struct { } func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeImages{}, middleware.After) if err != nil { return err @@ -96,34 +98,38 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeImages"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -132,13 +138,16 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpDescribeImagesValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeImages(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -150,6 +159,9 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -254,7 +266,6 @@ func newServiceMetadataMiddleware_opDescribeImages(region string) *awsmiddleware return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "DescribeImages", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribePullThroughCacheRules.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribePullThroughCacheRules.go index fc0b4f64e32..aff6fabeb07 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribePullThroughCacheRules.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribePullThroughCacheRules.go @@ -6,7 +6,6 @@ import ( "context" "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -79,6 +78,9 @@ type DescribePullThroughCacheRulesOutput struct { } func (c *Client) addOperationDescribePullThroughCacheRulesMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribePullThroughCacheRules{}, middleware.After) if err != nil { return err @@ -87,34 +89,38 @@ func (c *Client) addOperationDescribePullThroughCacheRulesMiddlewares(stack *mid if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DescribePullThroughCacheRules"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -123,10 +129,13 @@ func (c *Client) addOperationDescribePullThroughCacheRulesMiddlewares(stack *mid if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribePullThroughCacheRules(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -138,6 +147,9 @@ func (c *Client) addOperationDescribePullThroughCacheRulesMiddlewares(stack *mid if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -246,7 +258,6 @@ func newServiceMetadataMiddleware_opDescribePullThroughCacheRules(region string) return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "DescribePullThroughCacheRules", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRegistry.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRegistry.go index 79482a793bc..c6eeffe540a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRegistry.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRegistry.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -48,6 +48,9 @@ type DescribeRegistryOutput struct { } func (c *Client) addOperationDescribeRegistryMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeRegistry{}, middleware.After) if err != nil { return err @@ -56,34 +59,38 @@ func (c *Client) addOperationDescribeRegistryMiddlewares(stack *middleware.Stack if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeRegistry"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -92,10 +99,13 @@ func (c *Client) addOperationDescribeRegistryMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeRegistry(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -107,6 +117,9 @@ func (c *Client) addOperationDescribeRegistryMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -114,7 +127,6 @@ func newServiceMetadataMiddleware_opDescribeRegistry(region string) *awsmiddlewa return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "DescribeRegistry", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositories.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositories.go index ccf2a1b189c..e2b89ff3c2d 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositories.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_DescribeRepositories.go @@ -6,7 +6,6 @@ import ( "context" "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -81,6 +80,9 @@ type DescribeRepositoriesOutput struct { } func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeRepositories{}, middleware.After) if err != nil { return err @@ -89,34 +91,38 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeRepositories"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -125,10 +131,13 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeRepositories(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -140,6 +149,9 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -246,7 +258,6 @@ func newServiceMetadataMiddleware_opDescribeRepositories(region string) *awsmidd return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "DescribeRepositories", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAuthorizationToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAuthorizationToken.go index da84860fb75..842f8768b1a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAuthorizationToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetAuthorizationToken.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -62,6 +62,9 @@ type GetAuthorizationTokenOutput struct { } func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetAuthorizationToken{}, middleware.After) if err != nil { return err @@ -70,34 +73,38 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "GetAuthorizationToken"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -106,10 +113,13 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetAuthorizationToken(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -121,6 +131,9 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -128,7 +141,6 @@ func newServiceMetadataMiddleware_opGetAuthorizationToken(region string) *awsmid return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "GetAuthorizationToken", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetDownloadUrlForLayer.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetDownloadUrlForLayer.go index 1873ca1a019..80808c74002 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetDownloadUrlForLayer.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetDownloadUrlForLayer.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -66,6 +66,9 @@ type GetDownloadUrlForLayerOutput struct { } func (c *Client) addOperationGetDownloadUrlForLayerMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetDownloadUrlForLayer{}, middleware.After) if err != nil { return err @@ -74,34 +77,38 @@ func (c *Client) addOperationGetDownloadUrlForLayerMiddlewares(stack *middleware if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "GetDownloadUrlForLayer"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -110,13 +117,16 @@ func (c *Client) addOperationGetDownloadUrlForLayerMiddlewares(stack *middleware if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpGetDownloadUrlForLayerValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetDownloadUrlForLayer(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -128,6 +138,9 @@ func (c *Client) addOperationGetDownloadUrlForLayerMiddlewares(stack *middleware if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -135,7 +148,6 @@ func newServiceMetadataMiddleware_opGetDownloadUrlForLayer(region string) *awsmi return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "GetDownloadUrlForLayer", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicy.go index 43baec00a01..158119f9b9c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicy.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" "time" @@ -63,6 +63,9 @@ type GetLifecyclePolicyOutput struct { } func (c *Client) addOperationGetLifecyclePolicyMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetLifecyclePolicy{}, middleware.After) if err != nil { return err @@ -71,34 +74,38 @@ func (c *Client) addOperationGetLifecyclePolicyMiddlewares(stack *middleware.Sta if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "GetLifecyclePolicy"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -107,13 +114,16 @@ func (c *Client) addOperationGetLifecyclePolicyMiddlewares(stack *middleware.Sta if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpGetLifecyclePolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetLifecyclePolicy(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -125,6 +135,9 @@ func (c *Client) addOperationGetLifecyclePolicyMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -132,7 +145,6 @@ func newServiceMetadataMiddleware_opGetLifecyclePolicy(region string) *awsmiddle return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "GetLifecyclePolicy", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicyPreview.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicyPreview.go index 1b6c4c7dd6f..c88325e08c1 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicyPreview.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetLifecyclePolicyPreview.go @@ -6,7 +6,6 @@ import ( "context" "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithytime "github.com/aws/smithy-go/time" @@ -108,6 +107,9 @@ type GetLifecyclePolicyPreviewOutput struct { } func (c *Client) addOperationGetLifecyclePolicyPreviewMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetLifecyclePolicyPreview{}, middleware.After) if err != nil { return err @@ -116,34 +118,38 @@ func (c *Client) addOperationGetLifecyclePolicyPreviewMiddlewares(stack *middlew if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "GetLifecyclePolicyPreview"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -152,13 +158,16 @@ func (c *Client) addOperationGetLifecyclePolicyPreviewMiddlewares(stack *middlew if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpGetLifecyclePolicyPreviewValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetLifecyclePolicyPreview(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -170,6 +179,9 @@ func (c *Client) addOperationGetLifecyclePolicyPreviewMiddlewares(stack *middlew if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -281,8 +293,17 @@ type LifecyclePolicyPreviewCompleteWaiterOptions struct { // Set of options to modify how an operation is invoked. These apply to all // operations invoked for this client. Use functional options on operation call to // modify this list for per operation behavior. + // + // Passing options here is functionally equivalent to passing values to this + // config's ClientOptions field that extend the inner client's APIOptions directly. APIOptions []func(*middleware.Stack) error + // Functional options to be passed to all operations invoked by this client. + // + // Function values that modify the inner APIOptions are applied after the waiter + // config's own APIOptions modifiers. + ClientOptions []func(*Options) + // MinDelay is the minimum amount of time to delay between retries. If unset, // LifecyclePolicyPreviewCompleteWaiter will use default minimum delay of 5 // seconds. Note that MinDelay must resolve to a value lesser than or equal to the @@ -385,6 +406,9 @@ func (w *LifecyclePolicyPreviewCompleteWaiter) WaitForOutput(ctx context.Context out, err := w.client.GetLifecyclePolicyPreview(ctx, params, func(o *Options) { o.APIOptions = append(o.APIOptions, apiOptions...) + for _, opt := range options.ClientOptions { + opt(o) + } }) retryable, err := options.Retryable(ctx, params, out, err) @@ -460,7 +484,6 @@ func newServiceMetadataMiddleware_opGetLifecyclePolicyPreview(region string) *aw return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "GetLifecyclePolicyPreview", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryPolicy.go index 995a4c6d630..9e66e19217b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryPolicy.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -45,6 +45,9 @@ type GetRegistryPolicyOutput struct { } func (c *Client) addOperationGetRegistryPolicyMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetRegistryPolicy{}, middleware.After) if err != nil { return err @@ -53,34 +56,38 @@ func (c *Client) addOperationGetRegistryPolicyMiddlewares(stack *middleware.Stac if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "GetRegistryPolicy"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -89,10 +96,13 @@ func (c *Client) addOperationGetRegistryPolicyMiddlewares(stack *middleware.Stac if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRegistryPolicy(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -104,6 +114,9 @@ func (c *Client) addOperationGetRegistryPolicyMiddlewares(stack *middleware.Stac if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -111,7 +124,6 @@ func newServiceMetadataMiddleware_opGetRegistryPolicy(region string) *awsmiddlew return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "GetRegistryPolicy", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryScanningConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryScanningConfiguration.go index 46e3803fed5..ae28541948a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryScanningConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRegistryScanningConfiguration.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -46,6 +46,9 @@ type GetRegistryScanningConfigurationOutput struct { } func (c *Client) addOperationGetRegistryScanningConfigurationMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetRegistryScanningConfiguration{}, middleware.After) if err != nil { return err @@ -54,34 +57,38 @@ func (c *Client) addOperationGetRegistryScanningConfigurationMiddlewares(stack * if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "GetRegistryScanningConfiguration"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -90,10 +97,13 @@ func (c *Client) addOperationGetRegistryScanningConfigurationMiddlewares(stack * if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRegistryScanningConfiguration(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -105,6 +115,9 @@ func (c *Client) addOperationGetRegistryScanningConfigurationMiddlewares(stack * if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -112,7 +125,6 @@ func newServiceMetadataMiddleware_opGetRegistryScanningConfiguration(region stri return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "GetRegistryScanningConfiguration", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRepositoryPolicy.go index 0e87864b6a8..c74d9e684d4 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_GetRepositoryPolicy.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -59,6 +59,9 @@ type GetRepositoryPolicyOutput struct { } func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetRepositoryPolicy{}, middleware.After) if err != nil { return err @@ -67,34 +70,38 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "GetRepositoryPolicy"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -103,13 +110,16 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpGetRepositoryPolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRepositoryPolicy(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -121,6 +131,9 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -128,7 +141,6 @@ func newServiceMetadataMiddleware_opGetRepositoryPolicy(region string) *awsmiddl return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "GetRepositoryPolicy", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_InitiateLayerUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_InitiateLayerUpload.go index d00c727e242..678763f4ddb 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_InitiateLayerUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_InitiateLayerUpload.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -63,6 +63,9 @@ type InitiateLayerUploadOutput struct { } func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpInitiateLayerUpload{}, middleware.After) if err != nil { return err @@ -71,34 +74,38 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "InitiateLayerUpload"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -107,13 +114,16 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpInitiateLayerUploadValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opInitiateLayerUpload(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -125,6 +135,9 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -132,7 +145,6 @@ func newServiceMetadataMiddleware_opInitiateLayerUpload(region string) *awsmiddl return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "InitiateLayerUpload", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListImages.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListImages.go index f5cb17500d9..95a1ce2ca3f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListImages.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListImages.go @@ -6,7 +6,6 @@ import ( "context" "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -86,6 +85,9 @@ type ListImagesOutput struct { } func (c *Client) addOperationListImagesMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpListImages{}, middleware.After) if err != nil { return err @@ -94,34 +96,38 @@ func (c *Client) addOperationListImagesMiddlewares(stack *middleware.Stack, opti if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "ListImages"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -130,13 +136,16 @@ func (c *Client) addOperationListImagesMiddlewares(stack *middleware.Stack, opti if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpListImagesValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListImages(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -148,6 +157,9 @@ func (c *Client) addOperationListImagesMiddlewares(stack *middleware.Stack, opti if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -250,7 +262,6 @@ func newServiceMetadataMiddleware_opListImages(region string) *awsmiddleware.Reg return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "ListImages", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListTagsForResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListTagsForResource.go index 850acd2600e..a833645c982 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListTagsForResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ListTagsForResource.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -50,6 +50,9 @@ type ListTagsForResourceOutput struct { } func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpListTagsForResource{}, middleware.After) if err != nil { return err @@ -58,34 +61,38 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "ListTagsForResource"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -94,13 +101,16 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpListTagsForResourceValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListTagsForResource(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -112,6 +122,9 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -119,7 +132,6 @@ func newServiceMetadataMiddleware_opListTagsForResource(region string) *awsmiddl return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "ListTagsForResource", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImage.go index 00269b087cb..3bbebb033e3 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImage.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -77,6 +77,9 @@ type PutImageOutput struct { } func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutImage{}, middleware.After) if err != nil { return err @@ -85,34 +88,38 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "PutImage"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -121,13 +128,16 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpPutImageValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutImage(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -139,6 +149,9 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -146,7 +159,6 @@ func newServiceMetadataMiddleware_opPutImage(region string) *awsmiddleware.Regis return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "PutImage", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageScanningConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageScanningConfiguration.go index fbbc75cac37..e8ff335886f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageScanningConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageScanningConfiguration.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -71,6 +71,9 @@ type PutImageScanningConfigurationOutput struct { } func (c *Client) addOperationPutImageScanningConfigurationMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutImageScanningConfiguration{}, middleware.After) if err != nil { return err @@ -79,34 +82,38 @@ func (c *Client) addOperationPutImageScanningConfigurationMiddlewares(stack *mid if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "PutImageScanningConfiguration"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -115,13 +122,16 @@ func (c *Client) addOperationPutImageScanningConfigurationMiddlewares(stack *mid if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpPutImageScanningConfigurationValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutImageScanningConfiguration(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -133,6 +143,9 @@ func (c *Client) addOperationPutImageScanningConfigurationMiddlewares(stack *mid if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -140,7 +153,6 @@ func newServiceMetadataMiddleware_opPutImageScanningConfiguration(region string) return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "PutImageScanningConfiguration", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageTagMutability.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageTagMutability.go index bd5a2f4f9be..8fde2774f6b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageTagMutability.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutImageTagMutability.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -69,6 +69,9 @@ type PutImageTagMutabilityOutput struct { } func (c *Client) addOperationPutImageTagMutabilityMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutImageTagMutability{}, middleware.After) if err != nil { return err @@ -77,34 +80,38 @@ func (c *Client) addOperationPutImageTagMutabilityMiddlewares(stack *middleware. if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "PutImageTagMutability"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -113,13 +120,16 @@ func (c *Client) addOperationPutImageTagMutabilityMiddlewares(stack *middleware. if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpPutImageTagMutabilityValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutImageTagMutability(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -131,6 +141,9 @@ func (c *Client) addOperationPutImageTagMutabilityMiddlewares(stack *middleware. if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -138,7 +151,6 @@ func newServiceMetadataMiddleware_opPutImageTagMutability(region string) *awsmid return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "PutImageTagMutability", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutLifecyclePolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutLifecyclePolicy.go index 8a46dfecf05..133ddac4eef 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutLifecyclePolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutLifecyclePolicy.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -66,6 +66,9 @@ type PutLifecyclePolicyOutput struct { } func (c *Client) addOperationPutLifecyclePolicyMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutLifecyclePolicy{}, middleware.After) if err != nil { return err @@ -74,34 +77,38 @@ func (c *Client) addOperationPutLifecyclePolicyMiddlewares(stack *middleware.Sta if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "PutLifecyclePolicy"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -110,13 +117,16 @@ func (c *Client) addOperationPutLifecyclePolicyMiddlewares(stack *middleware.Sta if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpPutLifecyclePolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutLifecyclePolicy(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -128,6 +138,9 @@ func (c *Client) addOperationPutLifecyclePolicyMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -135,7 +148,6 @@ func newServiceMetadataMiddleware_opPutLifecyclePolicy(region string) *awsmiddle return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "PutLifecyclePolicy", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryPolicy.go index b02b9353a8c..92ca78c10f1 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryPolicy.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -57,6 +57,9 @@ type PutRegistryPolicyOutput struct { } func (c *Client) addOperationPutRegistryPolicyMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutRegistryPolicy{}, middleware.After) if err != nil { return err @@ -65,34 +68,38 @@ func (c *Client) addOperationPutRegistryPolicyMiddlewares(stack *middleware.Stac if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "PutRegistryPolicy"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -101,13 +108,16 @@ func (c *Client) addOperationPutRegistryPolicyMiddlewares(stack *middleware.Stac if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpPutRegistryPolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutRegistryPolicy(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -119,6 +129,9 @@ func (c *Client) addOperationPutRegistryPolicyMiddlewares(stack *middleware.Stac if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -126,7 +139,6 @@ func newServiceMetadataMiddleware_opPutRegistryPolicy(region string) *awsmiddlew return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "PutRegistryPolicy", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryScanningConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryScanningConfiguration.go index 4d0f207cfd1..74e4ac2895e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryScanningConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutRegistryScanningConfiguration.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -60,6 +60,9 @@ type PutRegistryScanningConfigurationOutput struct { } func (c *Client) addOperationPutRegistryScanningConfigurationMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutRegistryScanningConfiguration{}, middleware.After) if err != nil { return err @@ -68,34 +71,38 @@ func (c *Client) addOperationPutRegistryScanningConfigurationMiddlewares(stack * if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "PutRegistryScanningConfiguration"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -104,13 +111,16 @@ func (c *Client) addOperationPutRegistryScanningConfigurationMiddlewares(stack * if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpPutRegistryScanningConfigurationValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutRegistryScanningConfiguration(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -122,6 +132,9 @@ func (c *Client) addOperationPutRegistryScanningConfigurationMiddlewares(stack * if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -129,7 +142,6 @@ func newServiceMetadataMiddleware_opPutRegistryScanningConfiguration(region stri return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "PutRegistryScanningConfiguration", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutReplicationConfiguration.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutReplicationConfiguration.go index 5f655241519..9d5b3cc821e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutReplicationConfiguration.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_PutReplicationConfiguration.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -58,6 +58,9 @@ type PutReplicationConfigurationOutput struct { } func (c *Client) addOperationPutReplicationConfigurationMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutReplicationConfiguration{}, middleware.After) if err != nil { return err @@ -66,34 +69,38 @@ func (c *Client) addOperationPutReplicationConfigurationMiddlewares(stack *middl if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "PutReplicationConfiguration"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -102,13 +109,16 @@ func (c *Client) addOperationPutReplicationConfigurationMiddlewares(stack *middl if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpPutReplicationConfigurationValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutReplicationConfiguration(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -120,6 +130,9 @@ func (c *Client) addOperationPutReplicationConfigurationMiddlewares(stack *middl if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -127,7 +140,6 @@ func newServiceMetadataMiddleware_opPutReplicationConfiguration(region string) * return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "PutReplicationConfiguration", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_SetRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_SetRepositoryPolicy.go index 8f0eb1b57d3..62a700b2ad0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_SetRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_SetRepositoryPolicy.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -74,6 +74,9 @@ type SetRepositoryPolicyOutput struct { } func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpSetRepositoryPolicy{}, middleware.After) if err != nil { return err @@ -82,34 +85,38 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "SetRepositoryPolicy"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -118,13 +125,16 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpSetRepositoryPolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opSetRepositoryPolicy(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -136,6 +146,9 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -143,7 +156,6 @@ func newServiceMetadataMiddleware_opSetRepositoryPolicy(region string) *awsmiddl return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "SetRepositoryPolicy", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartImageScan.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartImageScan.go index 81b58403eb0..1a2cd6eb728 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartImageScan.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartImageScan.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -71,6 +71,9 @@ type StartImageScanOutput struct { } func (c *Client) addOperationStartImageScanMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpStartImageScan{}, middleware.After) if err != nil { return err @@ -79,34 +82,38 @@ func (c *Client) addOperationStartImageScanMiddlewares(stack *middleware.Stack, if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "StartImageScan"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -115,13 +122,16 @@ func (c *Client) addOperationStartImageScanMiddlewares(stack *middleware.Stack, if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpStartImageScanValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opStartImageScan(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -133,6 +143,9 @@ func (c *Client) addOperationStartImageScanMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -140,7 +153,6 @@ func newServiceMetadataMiddleware_opStartImageScan(region string) *awsmiddleware return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "StartImageScan", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartLifecyclePolicyPreview.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartLifecyclePolicyPreview.go index 69db5c084d7..95855b0b973 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartLifecyclePolicyPreview.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_StartLifecyclePolicyPreview.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -69,6 +69,9 @@ type StartLifecyclePolicyPreviewOutput struct { } func (c *Client) addOperationStartLifecyclePolicyPreviewMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpStartLifecyclePolicyPreview{}, middleware.After) if err != nil { return err @@ -77,34 +80,38 @@ func (c *Client) addOperationStartLifecyclePolicyPreviewMiddlewares(stack *middl if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "StartLifecyclePolicyPreview"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -113,13 +120,16 @@ func (c *Client) addOperationStartLifecyclePolicyPreviewMiddlewares(stack *middl if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpStartLifecyclePolicyPreviewValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opStartLifecyclePolicyPreview(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -131,6 +141,9 @@ func (c *Client) addOperationStartLifecyclePolicyPreviewMiddlewares(stack *middl if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -138,7 +151,6 @@ func newServiceMetadataMiddleware_opStartLifecyclePolicyPreview(region string) * return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "StartLifecyclePolicyPreview", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_TagResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_TagResource.go index 84e860d5719..683bc667e86 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_TagResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_TagResource.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecr/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -54,6 +54,9 @@ type TagResourceOutput struct { } func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpTagResource{}, middleware.After) if err != nil { return err @@ -62,34 +65,38 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "TagResource"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -98,13 +105,16 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpTagResourceValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opTagResource(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -116,6 +126,9 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -123,7 +136,6 @@ func newServiceMetadataMiddleware_opTagResource(region string) *awsmiddleware.Re return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "TagResource", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UntagResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UntagResource.go index 412384aa1eb..d1f57f68c50 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UntagResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UntagResource.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -50,6 +50,9 @@ type UntagResourceOutput struct { } func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpUntagResource{}, middleware.After) if err != nil { return err @@ -58,34 +61,38 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "UntagResource"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -94,13 +101,16 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpUntagResourceValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUntagResource(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -112,6 +122,9 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -119,7 +132,6 @@ func newServiceMetadataMiddleware_opUntagResource(region string) *awsmiddleware. return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "UntagResource", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UpdatePullThroughCacheRule.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UpdatePullThroughCacheRule.go new file mode 100644 index 00000000000..7b55a8016a8 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UpdatePullThroughCacheRule.go @@ -0,0 +1,158 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package ecr + +import ( + "context" + "fmt" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" + "time" +) + +// Updates an existing pull through cache rule. +func (c *Client) UpdatePullThroughCacheRule(ctx context.Context, params *UpdatePullThroughCacheRuleInput, optFns ...func(*Options)) (*UpdatePullThroughCacheRuleOutput, error) { + if params == nil { + params = &UpdatePullThroughCacheRuleInput{} + } + + result, metadata, err := c.invokeOperation(ctx, "UpdatePullThroughCacheRule", params, optFns, c.addOperationUpdatePullThroughCacheRuleMiddlewares) + if err != nil { + return nil, err + } + + out := result.(*UpdatePullThroughCacheRuleOutput) + out.ResultMetadata = metadata + return out, nil +} + +type UpdatePullThroughCacheRuleInput struct { + + // The Amazon Resource Name (ARN) of the Amazon Web Services Secrets Manager + // secret that identifies the credentials to authenticate to the upstream registry. + // + // This member is required. + CredentialArn *string + + // The repository name prefix to use when caching images from the source registry. + // + // This member is required. + EcrRepositoryPrefix *string + + // The Amazon Web Services account ID associated with the registry associated with + // the pull through cache rule. If you do not specify a registry, the default + // registry is assumed. + RegistryId *string + + noSmithyDocumentSerde +} + +type UpdatePullThroughCacheRuleOutput struct { + + // The Amazon Resource Name (ARN) of the Amazon Web Services Secrets Manager + // secret associated with the pull through cache rule. + CredentialArn *string + + // The Amazon ECR repository prefix associated with the pull through cache rule. + EcrRepositoryPrefix *string + + // The registry ID associated with the request. + RegistryId *string + + // The date and time, in JavaScript date format, when the pull through cache rule + // was updated. + UpdatedAt *time.Time + + // Metadata pertaining to the operation's result. + ResultMetadata middleware.Metadata + + noSmithyDocumentSerde +} + +func (c *Client) addOperationUpdatePullThroughCacheRuleMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } + err = stack.Serialize.Add(&awsAwsjson11_serializeOpUpdatePullThroughCacheRule{}, middleware.After) + if err != nil { + return err + } + err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpUpdatePullThroughCacheRule{}, middleware.After) + if err != nil { + return err + } + if err := addProtocolFinalizerMiddlewares(stack, options, "UpdatePullThroughCacheRule"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } + if err = addSetLoggerMiddleware(stack, options); err != nil { + return err + } + if err = addClientRequestID(stack); err != nil { + return err + } + if err = addComputeContentLength(stack); err != nil { + return err + } + if err = addResolveEndpointMiddleware(stack, options); err != nil { + return err + } + if err = addComputePayloadSHA256(stack); err != nil { + return err + } + if err = addRetry(stack, options); err != nil { + return err + } + if err = addRawResponseToMetadata(stack); err != nil { + return err + } + if err = addRecordResponseTiming(stack); err != nil { + return err + } + if err = addClientUserAgent(stack, options); err != nil { + return err + } + if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { + return err + } + if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + return err + } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } + if err = addOpUpdatePullThroughCacheRuleValidationMiddleware(stack); err != nil { + return err + } + if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUpdatePullThroughCacheRule(options.Region), middleware.Before); err != nil { + return err + } + if err = addRecursionDetection(stack); err != nil { + return err + } + if err = addRequestIDRetrieverMiddleware(stack); err != nil { + return err + } + if err = addResponseErrorMiddleware(stack); err != nil { + return err + } + if err = addRequestResponseLogging(stack, options); err != nil { + return err + } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + return nil +} + +func newServiceMetadataMiddleware_opUpdatePullThroughCacheRule(region string) *awsmiddleware.RegisterServiceMetadata { + return &awsmiddleware.RegisterServiceMetadata{ + Region: region, + ServiceID: ServiceID, + OperationName: "UpdatePullThroughCacheRule", + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UploadLayerPart.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UploadLayerPart.go index 60abba05659..b5160be8d58 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UploadLayerPart.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_UploadLayerPart.go @@ -4,8 +4,8 @@ package ecr import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -88,6 +88,9 @@ type UploadLayerPartOutput struct { } func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpUploadLayerPart{}, middleware.After) if err != nil { return err @@ -96,34 +99,38 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "UploadLayerPart"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -132,13 +139,16 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpUploadLayerPartValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUploadLayerPart(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -150,6 +160,9 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -157,7 +170,6 @@ func newServiceMetadataMiddleware_opUploadLayerPart(region string) *awsmiddlewar return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr", OperationName: "UploadLayerPart", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ValidatePullThroughCacheRule.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ValidatePullThroughCacheRule.go new file mode 100644 index 00000000000..7a97f666052 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/api_op_ValidatePullThroughCacheRule.go @@ -0,0 +1,163 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package ecr + +import ( + "context" + "fmt" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" +) + +// Validates an existing pull through cache rule for an upstream registry that +// requires authentication. This will retrieve the contents of the Amazon Web +// Services Secrets Manager secret, verify the syntax, and then validate that +// authentication to the upstream registry is successful. +func (c *Client) ValidatePullThroughCacheRule(ctx context.Context, params *ValidatePullThroughCacheRuleInput, optFns ...func(*Options)) (*ValidatePullThroughCacheRuleOutput, error) { + if params == nil { + params = &ValidatePullThroughCacheRuleInput{} + } + + result, metadata, err := c.invokeOperation(ctx, "ValidatePullThroughCacheRule", params, optFns, c.addOperationValidatePullThroughCacheRuleMiddlewares) + if err != nil { + return nil, err + } + + out := result.(*ValidatePullThroughCacheRuleOutput) + out.ResultMetadata = metadata + return out, nil +} + +type ValidatePullThroughCacheRuleInput struct { + + // The repository name prefix associated with the pull through cache rule. + // + // This member is required. + EcrRepositoryPrefix *string + + // The registry ID associated with the pull through cache rule. If you do not + // specify a registry, the default registry is assumed. + RegistryId *string + + noSmithyDocumentSerde +} + +type ValidatePullThroughCacheRuleOutput struct { + + // The Amazon Resource Name (ARN) of the Amazon Web Services Secrets Manager + // secret associated with the pull through cache rule. + CredentialArn *string + + // The Amazon ECR repository prefix associated with the pull through cache rule. + EcrRepositoryPrefix *string + + // The reason the validation failed. For more details about possible causes and + // how to address them, see Using pull through cache rules (https://docs.aws.amazon.com/AmazonECR/latest/userguide/pull-through-cache.html) + // in the Amazon Elastic Container Registry User Guide. + Failure *string + + // Whether or not the pull through cache rule was validated. If true , Amazon ECR + // was able to reach the upstream registry and authentication was successful. If + // false , there was an issue and validation failed. The failure reason indicates + // the cause. + IsValid bool + + // The registry ID associated with the request. + RegistryId *string + + // The upstream registry URL associated with the pull through cache rule. + UpstreamRegistryUrl *string + + // Metadata pertaining to the operation's result. + ResultMetadata middleware.Metadata + + noSmithyDocumentSerde +} + +func (c *Client) addOperationValidatePullThroughCacheRuleMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } + err = stack.Serialize.Add(&awsAwsjson11_serializeOpValidatePullThroughCacheRule{}, middleware.After) + if err != nil { + return err + } + err = stack.Deserialize.Add(&awsAwsjson11_deserializeOpValidatePullThroughCacheRule{}, middleware.After) + if err != nil { + return err + } + if err := addProtocolFinalizerMiddlewares(stack, options, "ValidatePullThroughCacheRule"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { + return err + } + if err = addSetLoggerMiddleware(stack, options); err != nil { + return err + } + if err = addClientRequestID(stack); err != nil { + return err + } + if err = addComputeContentLength(stack); err != nil { + return err + } + if err = addResolveEndpointMiddleware(stack, options); err != nil { + return err + } + if err = addComputePayloadSHA256(stack); err != nil { + return err + } + if err = addRetry(stack, options); err != nil { + return err + } + if err = addRawResponseToMetadata(stack); err != nil { + return err + } + if err = addRecordResponseTiming(stack); err != nil { + return err + } + if err = addClientUserAgent(stack, options); err != nil { + return err + } + if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { + return err + } + if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { + return err + } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } + if err = addOpValidatePullThroughCacheRuleValidationMiddleware(stack); err != nil { + return err + } + if err = stack.Initialize.Add(newServiceMetadataMiddleware_opValidatePullThroughCacheRule(options.Region), middleware.Before); err != nil { + return err + } + if err = addRecursionDetection(stack); err != nil { + return err + } + if err = addRequestIDRetrieverMiddleware(stack); err != nil { + return err + } + if err = addResponseErrorMiddleware(stack); err != nil { + return err + } + if err = addRequestResponseLogging(stack, options); err != nil { + return err + } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } + return nil +} + +func newServiceMetadataMiddleware_opValidatePullThroughCacheRule(region string) *awsmiddleware.RegisterServiceMetadata { + return &awsmiddleware.RegisterServiceMetadata{ + Region: region, + ServiceID: ServiceID, + OperationName: "ValidatePullThroughCacheRule", + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/auth.go new file mode 100644 index 00000000000..86ba7edf6b8 --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/auth.go @@ -0,0 +1,284 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package ecr + +import ( + "context" + "fmt" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + smithy "github.com/aws/smithy-go" + smithyauth "github.com/aws/smithy-go/auth" + "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" +) + +func bindAuthParamsRegion(params *AuthResolverParameters, _ interface{}, options Options) { + params.Region = options.Region +} + +type setLegacyContextSigningOptionsMiddleware struct { +} + +func (*setLegacyContextSigningOptionsMiddleware) ID() string { + return "setLegacyContextSigningOptions" +} + +func (m *setLegacyContextSigningOptionsMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + rscheme := getResolvedAuthScheme(ctx) + schemeID := rscheme.Scheme.SchemeID() + + if sn := awsmiddleware.GetSigningName(ctx); sn != "" { + if schemeID == "aws.auth#sigv4" { + smithyhttp.SetSigV4SigningName(&rscheme.SignerProperties, sn) + } else if schemeID == "aws.auth#sigv4a" { + smithyhttp.SetSigV4ASigningName(&rscheme.SignerProperties, sn) + } + } + + if sr := awsmiddleware.GetSigningRegion(ctx); sr != "" { + if schemeID == "aws.auth#sigv4" { + smithyhttp.SetSigV4SigningRegion(&rscheme.SignerProperties, sr) + } else if schemeID == "aws.auth#sigv4a" { + smithyhttp.SetSigV4ASigningRegions(&rscheme.SignerProperties, []string{sr}) + } + } + + return next.HandleFinalize(ctx, in) +} + +func addSetLegacyContextSigningOptionsMiddleware(stack *middleware.Stack) error { + return stack.Finalize.Insert(&setLegacyContextSigningOptionsMiddleware{}, "Signing", middleware.Before) +} + +type withAnonymous struct { + resolver AuthSchemeResolver +} + +var _ AuthSchemeResolver = (*withAnonymous)(nil) + +func (v *withAnonymous) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { + opts, err := v.resolver.ResolveAuthSchemes(ctx, params) + if err != nil { + return nil, err + } + + opts = append(opts, &smithyauth.Option{ + SchemeID: smithyauth.SchemeIDAnonymous, + }) + return opts, nil +} + +func wrapWithAnonymousAuth(options *Options) { + if _, ok := options.AuthSchemeResolver.(*defaultAuthSchemeResolver); !ok { + return + } + + options.AuthSchemeResolver = &withAnonymous{ + resolver: options.AuthSchemeResolver, + } +} + +// AuthResolverParameters contains the set of inputs necessary for auth scheme +// resolution. +type AuthResolverParameters struct { + // The name of the operation being invoked. + Operation string + + // The region in which the operation is being invoked. + Region string +} + +func bindAuthResolverParams(operation string, input interface{}, options Options) *AuthResolverParameters { + params := &AuthResolverParameters{ + Operation: operation, + } + + bindAuthParamsRegion(params, input, options) + + return params +} + +// AuthSchemeResolver returns a set of possible authentication options for an +// operation. +type AuthSchemeResolver interface { + ResolveAuthSchemes(context.Context, *AuthResolverParameters) ([]*smithyauth.Option, error) +} + +type defaultAuthSchemeResolver struct{} + +var _ AuthSchemeResolver = (*defaultAuthSchemeResolver)(nil) + +func (*defaultAuthSchemeResolver) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { + if overrides, ok := operationAuthOptions[params.Operation]; ok { + return overrides(params), nil + } + return serviceAuthOptions(params), nil +} + +var operationAuthOptions = map[string]func(*AuthResolverParameters) []*smithyauth.Option{} + +func serviceAuthOptions(params *AuthResolverParameters) []*smithyauth.Option { + return []*smithyauth.Option{ + { + SchemeID: smithyauth.SchemeIDSigV4, + SignerProperties: func() smithy.Properties { + var props smithy.Properties + smithyhttp.SetSigV4SigningName(&props, "ecr") + smithyhttp.SetSigV4SigningRegion(&props, params.Region) + return props + }(), + }, + } +} + +type resolveAuthSchemeMiddleware struct { + operation string + options Options +} + +func (*resolveAuthSchemeMiddleware) ID() string { + return "ResolveAuthScheme" +} + +func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + params := bindAuthResolverParams(m.operation, getOperationInput(ctx), m.options) + options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("resolve auth scheme: %w", err) + } + + scheme, ok := m.selectScheme(options) + if !ok { + return out, metadata, fmt.Errorf("could not select an auth scheme") + } + + ctx = setResolvedAuthScheme(ctx, scheme) + return next.HandleFinalize(ctx, in) +} + +func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) { + for _, option := range options { + if option.SchemeID == smithyauth.SchemeIDAnonymous { + return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true + } + + for _, scheme := range m.options.AuthSchemes { + if scheme.SchemeID() != option.SchemeID { + continue + } + + if scheme.IdentityResolver(m.options) != nil { + return newResolvedAuthScheme(scheme, option), true + } + } + } + + return nil, false +} + +type resolvedAuthSchemeKey struct{} + +type resolvedAuthScheme struct { + Scheme smithyhttp.AuthScheme + IdentityProperties smithy.Properties + SignerProperties smithy.Properties +} + +func newResolvedAuthScheme(scheme smithyhttp.AuthScheme, option *smithyauth.Option) *resolvedAuthScheme { + return &resolvedAuthScheme{ + Scheme: scheme, + IdentityProperties: option.IdentityProperties, + SignerProperties: option.SignerProperties, + } +} + +func setResolvedAuthScheme(ctx context.Context, scheme *resolvedAuthScheme) context.Context { + return middleware.WithStackValue(ctx, resolvedAuthSchemeKey{}, scheme) +} + +func getResolvedAuthScheme(ctx context.Context) *resolvedAuthScheme { + v, _ := middleware.GetStackValue(ctx, resolvedAuthSchemeKey{}).(*resolvedAuthScheme) + return v +} + +type getIdentityMiddleware struct { + options Options +} + +func (*getIdentityMiddleware) ID() string { + return "GetIdentity" +} + +func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + rscheme := getResolvedAuthScheme(ctx) + if rscheme == nil { + return out, metadata, fmt.Errorf("no resolved auth scheme") + } + + resolver := rscheme.Scheme.IdentityResolver(m.options) + if resolver == nil { + return out, metadata, fmt.Errorf("no identity resolver") + } + + identity, err := resolver.GetIdentity(ctx, rscheme.IdentityProperties) + if err != nil { + return out, metadata, fmt.Errorf("get identity: %w", err) + } + + ctx = setIdentity(ctx, identity) + return next.HandleFinalize(ctx, in) +} + +type identityKey struct{} + +func setIdentity(ctx context.Context, identity smithyauth.Identity) context.Context { + return middleware.WithStackValue(ctx, identityKey{}, identity) +} + +func getIdentity(ctx context.Context) smithyauth.Identity { + v, _ := middleware.GetStackValue(ctx, identityKey{}).(smithyauth.Identity) + return v +} + +type signRequestMiddleware struct { +} + +func (*signRequestMiddleware) ID() string { + return "Signing" +} + +func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + req, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, fmt.Errorf("unexpected transport type %T", in.Request) + } + + rscheme := getResolvedAuthScheme(ctx) + if rscheme == nil { + return out, metadata, fmt.Errorf("no resolved auth scheme") + } + + identity := getIdentity(ctx) + if identity == nil { + return out, metadata, fmt.Errorf("no identity") + } + + signer := rscheme.Scheme.Signer() + if signer == nil { + return out, metadata, fmt.Errorf("no signer") + } + + if err := signer.SignRequest(ctx, req, identity, rscheme.SignerProperties); err != nil { + return out, metadata, fmt.Errorf("sign request: %w", err) + } + + return next.HandleFinalize(ctx, in) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/deserializers.go index 79c79b7aba6..d4c99343a8b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/deserializers.go @@ -88,9 +88,6 @@ func awsAwsjson11_deserializeOpErrorBatchCheckLayerAvailability(response *smithy errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -98,7 +95,7 @@ func awsAwsjson11_deserializeOpErrorBatchCheckLayerAvailability(response *smithy body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -110,13 +107,12 @@ func awsAwsjson11_deserializeOpErrorBatchCheckLayerAvailability(response *smithy } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -205,9 +201,6 @@ func awsAwsjson11_deserializeOpErrorBatchDeleteImage(response *smithyhttp.Respon errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -215,7 +208,7 @@ func awsAwsjson11_deserializeOpErrorBatchDeleteImage(response *smithyhttp.Respon body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -227,13 +220,12 @@ func awsAwsjson11_deserializeOpErrorBatchDeleteImage(response *smithyhttp.Respon } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -322,9 +314,6 @@ func awsAwsjson11_deserializeOpErrorBatchGetImage(response *smithyhttp.Response, errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -332,7 +321,7 @@ func awsAwsjson11_deserializeOpErrorBatchGetImage(response *smithyhttp.Response, body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -344,23 +333,28 @@ func awsAwsjson11_deserializeOpErrorBatchGetImage(response *smithyhttp.Response, } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) + case strings.EqualFold("LimitExceededException", errorCode): + return awsAwsjson11_deserializeErrorLimitExceededException(response, errorBody) + case strings.EqualFold("RepositoryNotFoundException", errorCode): return awsAwsjson11_deserializeErrorRepositoryNotFoundException(response, errorBody) case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnableToGetUpstreamImageException", errorCode): + return awsAwsjson11_deserializeErrorUnableToGetUpstreamImageException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -439,9 +433,6 @@ func awsAwsjson11_deserializeOpErrorBatchGetRepositoryScanningConfiguration(resp errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -449,7 +440,7 @@ func awsAwsjson11_deserializeOpErrorBatchGetRepositoryScanningConfiguration(resp body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -461,13 +452,12 @@ func awsAwsjson11_deserializeOpErrorBatchGetRepositoryScanningConfiguration(resp } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -559,9 +549,6 @@ func awsAwsjson11_deserializeOpErrorCompleteLayerUpload(response *smithyhttp.Res errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -569,7 +556,7 @@ func awsAwsjson11_deserializeOpErrorCompleteLayerUpload(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -581,13 +568,12 @@ func awsAwsjson11_deserializeOpErrorCompleteLayerUpload(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("EmptyUploadException", errorCode): return awsAwsjson11_deserializeErrorEmptyUploadException(response, errorBody) @@ -694,9 +680,6 @@ func awsAwsjson11_deserializeOpErrorCreatePullThroughCacheRule(response *smithyh errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -704,7 +687,7 @@ func awsAwsjson11_deserializeOpErrorCreatePullThroughCacheRule(response *smithyh body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -716,13 +699,12 @@ func awsAwsjson11_deserializeOpErrorCreatePullThroughCacheRule(response *smithyh } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -733,9 +715,18 @@ func awsAwsjson11_deserializeOpErrorCreatePullThroughCacheRule(response *smithyh case strings.EqualFold("PullThroughCacheRuleAlreadyExistsException", errorCode): return awsAwsjson11_deserializeErrorPullThroughCacheRuleAlreadyExistsException(response, errorBody) + case strings.EqualFold("SecretNotFoundException", errorCode): + return awsAwsjson11_deserializeErrorSecretNotFoundException(response, errorBody) + case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnableToAccessSecretException", errorCode): + return awsAwsjson11_deserializeErrorUnableToAccessSecretException(response, errorBody) + + case strings.EqualFold("UnableToDecryptSecretValueException", errorCode): + return awsAwsjson11_deserializeErrorUnableToDecryptSecretValueException(response, errorBody) + case strings.EqualFold("UnsupportedUpstreamRegistryException", errorCode): return awsAwsjson11_deserializeErrorUnsupportedUpstreamRegistryException(response, errorBody) @@ -820,9 +811,6 @@ func awsAwsjson11_deserializeOpErrorCreateRepository(response *smithyhttp.Respon errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -830,7 +818,7 @@ func awsAwsjson11_deserializeOpErrorCreateRepository(response *smithyhttp.Respon body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -842,13 +830,12 @@ func awsAwsjson11_deserializeOpErrorCreateRepository(response *smithyhttp.Respon } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -949,9 +936,6 @@ func awsAwsjson11_deserializeOpErrorDeleteLifecyclePolicy(response *smithyhttp.R errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -959,7 +943,7 @@ func awsAwsjson11_deserializeOpErrorDeleteLifecyclePolicy(response *smithyhttp.R body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -971,13 +955,12 @@ func awsAwsjson11_deserializeOpErrorDeleteLifecyclePolicy(response *smithyhttp.R } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -991,6 +974,9 @@ func awsAwsjson11_deserializeOpErrorDeleteLifecyclePolicy(response *smithyhttp.R case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("ValidationException", errorCode): + return awsAwsjson11_deserializeErrorValidationException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -1069,9 +1055,6 @@ func awsAwsjson11_deserializeOpErrorDeletePullThroughCacheRule(response *smithyh errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1079,7 +1062,7 @@ func awsAwsjson11_deserializeOpErrorDeletePullThroughCacheRule(response *smithyh body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1091,13 +1074,12 @@ func awsAwsjson11_deserializeOpErrorDeletePullThroughCacheRule(response *smithyh } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -1189,9 +1171,6 @@ func awsAwsjson11_deserializeOpErrorDeleteRegistryPolicy(response *smithyhttp.Re errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1199,7 +1178,7 @@ func awsAwsjson11_deserializeOpErrorDeleteRegistryPolicy(response *smithyhttp.Re body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1211,13 +1190,12 @@ func awsAwsjson11_deserializeOpErrorDeleteRegistryPolicy(response *smithyhttp.Re } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -1309,9 +1287,6 @@ func awsAwsjson11_deserializeOpErrorDeleteRepository(response *smithyhttp.Respon errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1319,7 +1294,7 @@ func awsAwsjson11_deserializeOpErrorDeleteRepository(response *smithyhttp.Respon body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1331,13 +1306,12 @@ func awsAwsjson11_deserializeOpErrorDeleteRepository(response *smithyhttp.Respon } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -1432,9 +1406,6 @@ func awsAwsjson11_deserializeOpErrorDeleteRepositoryPolicy(response *smithyhttp. errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1442,7 +1413,7 @@ func awsAwsjson11_deserializeOpErrorDeleteRepositoryPolicy(response *smithyhttp. body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1454,13 +1425,12 @@ func awsAwsjson11_deserializeOpErrorDeleteRepositoryPolicy(response *smithyhttp. } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -1552,9 +1522,6 @@ func awsAwsjson11_deserializeOpErrorDescribeImageReplicationStatus(response *smi errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1562,7 +1529,7 @@ func awsAwsjson11_deserializeOpErrorDescribeImageReplicationStatus(response *smi body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1574,13 +1541,12 @@ func awsAwsjson11_deserializeOpErrorDescribeImageReplicationStatus(response *smi } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("ImageNotFoundException", errorCode): return awsAwsjson11_deserializeErrorImageNotFoundException(response, errorBody) @@ -1675,9 +1641,6 @@ func awsAwsjson11_deserializeOpErrorDescribeImages(response *smithyhttp.Response errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1685,7 +1648,7 @@ func awsAwsjson11_deserializeOpErrorDescribeImages(response *smithyhttp.Response body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1697,13 +1660,12 @@ func awsAwsjson11_deserializeOpErrorDescribeImages(response *smithyhttp.Response } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("ImageNotFoundException", errorCode): return awsAwsjson11_deserializeErrorImageNotFoundException(response, errorBody) @@ -1795,9 +1757,6 @@ func awsAwsjson11_deserializeOpErrorDescribeImageScanFindings(response *smithyht errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1805,7 +1764,7 @@ func awsAwsjson11_deserializeOpErrorDescribeImageScanFindings(response *smithyht body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1817,13 +1776,12 @@ func awsAwsjson11_deserializeOpErrorDescribeImageScanFindings(response *smithyht } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("ImageNotFoundException", errorCode): return awsAwsjson11_deserializeErrorImageNotFoundException(response, errorBody) @@ -1921,9 +1879,6 @@ func awsAwsjson11_deserializeOpErrorDescribePullThroughCacheRules(response *smit errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1931,7 +1886,7 @@ func awsAwsjson11_deserializeOpErrorDescribePullThroughCacheRules(response *smit body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1943,13 +1898,12 @@ func awsAwsjson11_deserializeOpErrorDescribePullThroughCacheRules(response *smit } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2041,9 +1995,6 @@ func awsAwsjson11_deserializeOpErrorDescribeRegistry(response *smithyhttp.Respon errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2051,7 +2002,7 @@ func awsAwsjson11_deserializeOpErrorDescribeRegistry(response *smithyhttp.Respon body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2063,13 +2014,12 @@ func awsAwsjson11_deserializeOpErrorDescribeRegistry(response *smithyhttp.Respon } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2158,9 +2108,6 @@ func awsAwsjson11_deserializeOpErrorDescribeRepositories(response *smithyhttp.Re errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2168,7 +2115,7 @@ func awsAwsjson11_deserializeOpErrorDescribeRepositories(response *smithyhttp.Re body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2180,13 +2127,12 @@ func awsAwsjson11_deserializeOpErrorDescribeRepositories(response *smithyhttp.Re } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2275,9 +2221,6 @@ func awsAwsjson11_deserializeOpErrorGetAuthorizationToken(response *smithyhttp.R errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2285,7 +2228,7 @@ func awsAwsjson11_deserializeOpErrorGetAuthorizationToken(response *smithyhttp.R body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2297,13 +2240,12 @@ func awsAwsjson11_deserializeOpErrorGetAuthorizationToken(response *smithyhttp.R } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2389,9 +2331,6 @@ func awsAwsjson11_deserializeOpErrorGetDownloadUrlForLayer(response *smithyhttp. errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2399,7 +2338,7 @@ func awsAwsjson11_deserializeOpErrorGetDownloadUrlForLayer(response *smithyhttp. body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2411,13 +2350,12 @@ func awsAwsjson11_deserializeOpErrorGetDownloadUrlForLayer(response *smithyhttp. } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2434,6 +2372,9 @@ func awsAwsjson11_deserializeOpErrorGetDownloadUrlForLayer(response *smithyhttp. case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("UnableToGetUpstreamLayerException", errorCode): + return awsAwsjson11_deserializeErrorUnableToGetUpstreamLayerException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -2512,9 +2453,6 @@ func awsAwsjson11_deserializeOpErrorGetLifecyclePolicy(response *smithyhttp.Resp errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2522,7 +2460,7 @@ func awsAwsjson11_deserializeOpErrorGetLifecyclePolicy(response *smithyhttp.Resp body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2534,13 +2472,12 @@ func awsAwsjson11_deserializeOpErrorGetLifecyclePolicy(response *smithyhttp.Resp } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2554,6 +2491,9 @@ func awsAwsjson11_deserializeOpErrorGetLifecyclePolicy(response *smithyhttp.Resp case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("ValidationException", errorCode): + return awsAwsjson11_deserializeErrorValidationException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -2632,9 +2572,6 @@ func awsAwsjson11_deserializeOpErrorGetLifecyclePolicyPreview(response *smithyht errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2642,7 +2579,7 @@ func awsAwsjson11_deserializeOpErrorGetLifecyclePolicyPreview(response *smithyht body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2654,13 +2591,12 @@ func awsAwsjson11_deserializeOpErrorGetLifecyclePolicyPreview(response *smithyht } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2674,6 +2610,9 @@ func awsAwsjson11_deserializeOpErrorGetLifecyclePolicyPreview(response *smithyht case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("ValidationException", errorCode): + return awsAwsjson11_deserializeErrorValidationException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -2752,9 +2691,6 @@ func awsAwsjson11_deserializeOpErrorGetRegistryPolicy(response *smithyhttp.Respo errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2762,7 +2698,7 @@ func awsAwsjson11_deserializeOpErrorGetRegistryPolicy(response *smithyhttp.Respo body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2774,13 +2710,12 @@ func awsAwsjson11_deserializeOpErrorGetRegistryPolicy(response *smithyhttp.Respo } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2872,9 +2807,6 @@ func awsAwsjson11_deserializeOpErrorGetRegistryScanningConfiguration(response *s errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2882,7 +2814,7 @@ func awsAwsjson11_deserializeOpErrorGetRegistryScanningConfiguration(response *s body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2894,13 +2826,12 @@ func awsAwsjson11_deserializeOpErrorGetRegistryScanningConfiguration(response *s } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2989,9 +2920,6 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryPolicy(response *smithyhttp.Res errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2999,7 +2927,7 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryPolicy(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -3011,13 +2939,12 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryPolicy(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -3109,9 +3036,6 @@ func awsAwsjson11_deserializeOpErrorInitiateLayerUpload(response *smithyhttp.Res errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -3119,7 +3043,7 @@ func awsAwsjson11_deserializeOpErrorInitiateLayerUpload(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -3131,13 +3055,12 @@ func awsAwsjson11_deserializeOpErrorInitiateLayerUpload(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -3229,9 +3152,6 @@ func awsAwsjson11_deserializeOpErrorListImages(response *smithyhttp.Response, me errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -3239,7 +3159,7 @@ func awsAwsjson11_deserializeOpErrorListImages(response *smithyhttp.Response, me body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -3251,13 +3171,12 @@ func awsAwsjson11_deserializeOpErrorListImages(response *smithyhttp.Response, me } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -3346,9 +3265,6 @@ func awsAwsjson11_deserializeOpErrorListTagsForResource(response *smithyhttp.Res errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -3356,7 +3272,7 @@ func awsAwsjson11_deserializeOpErrorListTagsForResource(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -3368,13 +3284,12 @@ func awsAwsjson11_deserializeOpErrorListTagsForResource(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -3463,9 +3378,6 @@ func awsAwsjson11_deserializeOpErrorPutImage(response *smithyhttp.Response, meta errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -3473,7 +3385,7 @@ func awsAwsjson11_deserializeOpErrorPutImage(response *smithyhttp.Response, meta body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -3485,13 +3397,12 @@ func awsAwsjson11_deserializeOpErrorPutImage(response *smithyhttp.Response, meta } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("ImageAlreadyExistsException", errorCode): return awsAwsjson11_deserializeErrorImageAlreadyExistsException(response, errorBody) @@ -3601,9 +3512,6 @@ func awsAwsjson11_deserializeOpErrorPutImageScanningConfiguration(response *smit errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -3611,7 +3519,7 @@ func awsAwsjson11_deserializeOpErrorPutImageScanningConfiguration(response *smit body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -3623,13 +3531,12 @@ func awsAwsjson11_deserializeOpErrorPutImageScanningConfiguration(response *smit } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -3721,9 +3628,6 @@ func awsAwsjson11_deserializeOpErrorPutImageTagMutability(response *smithyhttp.R errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -3731,7 +3635,7 @@ func awsAwsjson11_deserializeOpErrorPutImageTagMutability(response *smithyhttp.R body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -3743,13 +3647,12 @@ func awsAwsjson11_deserializeOpErrorPutImageTagMutability(response *smithyhttp.R } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -3838,9 +3741,6 @@ func awsAwsjson11_deserializeOpErrorPutLifecyclePolicy(response *smithyhttp.Resp errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -3848,7 +3748,7 @@ func awsAwsjson11_deserializeOpErrorPutLifecyclePolicy(response *smithyhttp.Resp body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -3860,13 +3760,12 @@ func awsAwsjson11_deserializeOpErrorPutLifecyclePolicy(response *smithyhttp.Resp } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -3877,6 +3776,9 @@ func awsAwsjson11_deserializeOpErrorPutLifecyclePolicy(response *smithyhttp.Resp case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("ValidationException", errorCode): + return awsAwsjson11_deserializeErrorValidationException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -3955,9 +3857,6 @@ func awsAwsjson11_deserializeOpErrorPutRegistryPolicy(response *smithyhttp.Respo errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -3965,7 +3864,7 @@ func awsAwsjson11_deserializeOpErrorPutRegistryPolicy(response *smithyhttp.Respo body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -3977,13 +3876,12 @@ func awsAwsjson11_deserializeOpErrorPutRegistryPolicy(response *smithyhttp.Respo } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -4072,9 +3970,6 @@ func awsAwsjson11_deserializeOpErrorPutRegistryScanningConfiguration(response *s errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -4082,7 +3977,7 @@ func awsAwsjson11_deserializeOpErrorPutRegistryScanningConfiguration(response *s body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -4094,13 +3989,12 @@ func awsAwsjson11_deserializeOpErrorPutRegistryScanningConfiguration(response *s } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -4189,9 +4083,6 @@ func awsAwsjson11_deserializeOpErrorPutReplicationConfiguration(response *smithy errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -4199,7 +4090,7 @@ func awsAwsjson11_deserializeOpErrorPutReplicationConfiguration(response *smithy body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -4211,13 +4102,12 @@ func awsAwsjson11_deserializeOpErrorPutReplicationConfiguration(response *smithy } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -4306,9 +4196,6 @@ func awsAwsjson11_deserializeOpErrorSetRepositoryPolicy(response *smithyhttp.Res errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -4316,7 +4203,7 @@ func awsAwsjson11_deserializeOpErrorSetRepositoryPolicy(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -4328,13 +4215,12 @@ func awsAwsjson11_deserializeOpErrorSetRepositoryPolicy(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -4423,9 +4309,6 @@ func awsAwsjson11_deserializeOpErrorStartImageScan(response *smithyhttp.Response errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -4433,7 +4316,7 @@ func awsAwsjson11_deserializeOpErrorStartImageScan(response *smithyhttp.Response body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -4445,13 +4328,12 @@ func awsAwsjson11_deserializeOpErrorStartImageScan(response *smithyhttp.Response } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("ImageNotFoundException", errorCode): return awsAwsjson11_deserializeErrorImageNotFoundException(response, errorBody) @@ -4552,9 +4434,6 @@ func awsAwsjson11_deserializeOpErrorStartLifecyclePolicyPreview(response *smithy errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -4562,7 +4441,7 @@ func awsAwsjson11_deserializeOpErrorStartLifecyclePolicyPreview(response *smithy body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -4574,13 +4453,12 @@ func awsAwsjson11_deserializeOpErrorStartLifecyclePolicyPreview(response *smithy } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -4597,6 +4475,9 @@ func awsAwsjson11_deserializeOpErrorStartLifecyclePolicyPreview(response *smithy case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) + case strings.EqualFold("ValidationException", errorCode): + return awsAwsjson11_deserializeErrorValidationException(response, errorBody) + default: genericError := &smithy.GenericAPIError{ Code: errorCode, @@ -4675,9 +4556,6 @@ func awsAwsjson11_deserializeOpErrorTagResource(response *smithyhttp.Response, m errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -4685,7 +4563,7 @@ func awsAwsjson11_deserializeOpErrorTagResource(response *smithyhttp.Response, m body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -4697,13 +4575,12 @@ func awsAwsjson11_deserializeOpErrorTagResource(response *smithyhttp.Response, m } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -4798,9 +4675,6 @@ func awsAwsjson11_deserializeOpErrorUntagResource(response *smithyhttp.Response, errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -4808,7 +4682,7 @@ func awsAwsjson11_deserializeOpErrorUntagResource(response *smithyhttp.Response, body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -4820,13 +4694,12 @@ func awsAwsjson11_deserializeOpErrorUntagResource(response *smithyhttp.Response, } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -4853,14 +4726,14 @@ func awsAwsjson11_deserializeOpErrorUntagResource(response *smithyhttp.Response, } } -type awsAwsjson11_deserializeOpUploadLayerPart struct { +type awsAwsjson11_deserializeOpUpdatePullThroughCacheRule struct { } -func (*awsAwsjson11_deserializeOpUploadLayerPart) ID() string { +func (*awsAwsjson11_deserializeOpUpdatePullThroughCacheRule) ID() string { return "OperationDeserializer" } -func (m *awsAwsjson11_deserializeOpUploadLayerPart) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( +func (m *awsAwsjson11_deserializeOpUpdatePullThroughCacheRule) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( out middleware.DeserializeOutput, metadata middleware.Metadata, err error, ) { out, metadata, err = next.HandleDeserialize(ctx, in) @@ -4874,9 +4747,9 @@ func (m *awsAwsjson11_deserializeOpUploadLayerPart) HandleDeserialize(ctx contex } if response.StatusCode < 200 || response.StatusCode >= 300 { - return out, metadata, awsAwsjson11_deserializeOpErrorUploadLayerPart(response, &metadata) + return out, metadata, awsAwsjson11_deserializeOpErrorUpdatePullThroughCacheRule(response, &metadata) } - output := &UploadLayerPartOutput{} + output := &UpdatePullThroughCacheRuleOutput{} out.Result = output var buff [1024]byte @@ -4896,7 +4769,7 @@ func (m *awsAwsjson11_deserializeOpUploadLayerPart) HandleDeserialize(ctx contex return out, metadata, err } - err = awsAwsjson11_deserializeOpDocumentUploadLayerPartOutput(&output, shape) + err = awsAwsjson11_deserializeOpDocumentUpdatePullThroughCacheRuleOutput(&output, shape) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -4910,7 +4783,7 @@ func (m *awsAwsjson11_deserializeOpUploadLayerPart) HandleDeserialize(ctx contex return out, metadata, err } -func awsAwsjson11_deserializeOpErrorUploadLayerPart(response *smithyhttp.Response, metadata *middleware.Metadata) error { +func awsAwsjson11_deserializeOpErrorUpdatePullThroughCacheRule(response *smithyhttp.Response, metadata *middleware.Metadata) error { var errorBuffer bytes.Buffer if _, err := io.Copy(&errorBuffer, response.Body); err != nil { return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} @@ -4921,9 +4794,6 @@ func awsAwsjson11_deserializeOpErrorUploadLayerPart(response *smithyhttp.Respons errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -4931,7 +4801,7 @@ func awsAwsjson11_deserializeOpErrorUploadLayerPart(response *smithyhttp.Respons body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -4943,34 +4813,33 @@ func awsAwsjson11_deserializeOpErrorUploadLayerPart(response *smithyhttp.Respons } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { - case strings.EqualFold("InvalidLayerPartException", errorCode): - return awsAwsjson11_deserializeErrorInvalidLayerPartException(response, errorBody) - case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) - case strings.EqualFold("KmsException", errorCode): - return awsAwsjson11_deserializeErrorKmsException(response, errorBody) - - case strings.EqualFold("LimitExceededException", errorCode): - return awsAwsjson11_deserializeErrorLimitExceededException(response, errorBody) + case strings.EqualFold("PullThroughCacheRuleNotFoundException", errorCode): + return awsAwsjson11_deserializeErrorPullThroughCacheRuleNotFoundException(response, errorBody) - case strings.EqualFold("RepositoryNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorRepositoryNotFoundException(response, errorBody) + case strings.EqualFold("SecretNotFoundException", errorCode): + return awsAwsjson11_deserializeErrorSecretNotFoundException(response, errorBody) case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) - case strings.EqualFold("UploadNotFoundException", errorCode): - return awsAwsjson11_deserializeErrorUploadNotFoundException(response, errorBody) + case strings.EqualFold("UnableToAccessSecretException", errorCode): + return awsAwsjson11_deserializeErrorUnableToAccessSecretException(response, errorBody) + + case strings.EqualFold("UnableToDecryptSecretValueException", errorCode): + return awsAwsjson11_deserializeErrorUnableToDecryptSecretValueException(response, errorBody) + + case strings.EqualFold("ValidationException", errorCode): + return awsAwsjson11_deserializeErrorValidationException(response, errorBody) default: genericError := &smithy.GenericAPIError{ @@ -4982,11 +4851,36 @@ func awsAwsjson11_deserializeOpErrorUploadLayerPart(response *smithyhttp.Respons } } -func awsAwsjson11_deserializeErrorEmptyUploadException(response *smithyhttp.Response, errorBody *bytes.Reader) error { +type awsAwsjson11_deserializeOpUploadLayerPart struct { +} + +func (*awsAwsjson11_deserializeOpUploadLayerPart) ID() string { + return "OperationDeserializer" +} + +func (m *awsAwsjson11_deserializeOpUploadLayerPart) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( + out middleware.DeserializeOutput, metadata middleware.Metadata, err error, +) { + out, metadata, err = next.HandleDeserialize(ctx, in) + if err != nil { + return out, metadata, err + } + + response, ok := out.RawResponse.(*smithyhttp.Response) + if !ok { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} + } + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return out, metadata, awsAwsjson11_deserializeOpErrorUploadLayerPart(response, &metadata) + } + output := &UploadLayerPartOutput{} + out.Result = output + var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(errorBody, ringBuffer) + body := io.TeeReader(response.Body, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() var shape interface{} @@ -4997,12 +4891,10 @@ func awsAwsjson11_deserializeErrorEmptyUploadException(response *smithyhttp.Resp Err: fmt.Errorf("failed to decode response body, %w", err), Snapshot: snapshot.Bytes(), } - return err + return out, metadata, err } - output := &types.EmptyUploadException{} - err := awsAwsjson11_deserializeDocumentEmptyUploadException(&output, shape) - + err = awsAwsjson11_deserializeOpDocumentUploadLayerPartOutput(&output, shape) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -5010,22 +4902,32 @@ func awsAwsjson11_deserializeErrorEmptyUploadException(response *smithyhttp.Resp Err: fmt.Errorf("failed to decode response body, %w", err), Snapshot: snapshot.Bytes(), } - return err + return out, metadata, err } - errorBody.Seek(0, io.SeekStart) - return output + return out, metadata, err } -func awsAwsjson11_deserializeErrorImageAlreadyExistsException(response *smithyhttp.Response, errorBody *bytes.Reader) error { +func awsAwsjson11_deserializeOpErrorUploadLayerPart(response *smithyhttp.Response, metadata *middleware.Metadata) error { + var errorBuffer bytes.Buffer + if _, err := io.Copy(&errorBuffer, response.Body); err != nil { + return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} + } + errorBody := bytes.NewReader(errorBuffer.Bytes()) + + errorCode := "UnknownError" + errorMessage := errorCode + + headerCode := response.Header.Get("X-Amzn-ErrorType") + var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - var shape interface{} - if err := decoder.Decode(&shape); err != nil && err != io.EOF { + bodyInfo, err := getProtocolErrorInfo(decoder) + if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) err = &smithy.DeserializationError{ @@ -5035,28 +4937,75 @@ func awsAwsjson11_deserializeErrorImageAlreadyExistsException(response *smithyht return err } - output := &types.ImageAlreadyExistsException{} - err := awsAwsjson11_deserializeDocumentImageAlreadyExistsException(&output, shape) + errorBody.Seek(0, io.SeekStart) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) + } + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message + } + switch { + case strings.EqualFold("InvalidLayerPartException", errorCode): + return awsAwsjson11_deserializeErrorInvalidLayerPartException(response, errorBody) - if err != nil { - var snapshot bytes.Buffer - io.Copy(&snapshot, ringBuffer) - err = &smithy.DeserializationError{ - Err: fmt.Errorf("failed to decode response body, %w", err), - Snapshot: snapshot.Bytes(), + case strings.EqualFold("InvalidParameterException", errorCode): + return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) + + case strings.EqualFold("KmsException", errorCode): + return awsAwsjson11_deserializeErrorKmsException(response, errorBody) + + case strings.EqualFold("LimitExceededException", errorCode): + return awsAwsjson11_deserializeErrorLimitExceededException(response, errorBody) + + case strings.EqualFold("RepositoryNotFoundException", errorCode): + return awsAwsjson11_deserializeErrorRepositoryNotFoundException(response, errorBody) + + case strings.EqualFold("ServerException", errorCode): + return awsAwsjson11_deserializeErrorServerException(response, errorBody) + + case strings.EqualFold("UploadNotFoundException", errorCode): + return awsAwsjson11_deserializeErrorUploadNotFoundException(response, errorBody) + + default: + genericError := &smithy.GenericAPIError{ + Code: errorCode, + Message: errorMessage, } - return err + return genericError + } +} - errorBody.Seek(0, io.SeekStart) - return output +type awsAwsjson11_deserializeOpValidatePullThroughCacheRule struct { } -func awsAwsjson11_deserializeErrorImageDigestDoesNotMatchException(response *smithyhttp.Response, errorBody *bytes.Reader) error { +func (*awsAwsjson11_deserializeOpValidatePullThroughCacheRule) ID() string { + return "OperationDeserializer" +} + +func (m *awsAwsjson11_deserializeOpValidatePullThroughCacheRule) HandleDeserialize(ctx context.Context, in middleware.DeserializeInput, next middleware.DeserializeHandler) ( + out middleware.DeserializeOutput, metadata middleware.Metadata, err error, +) { + out, metadata, err = next.HandleDeserialize(ctx, in) + if err != nil { + return out, metadata, err + } + + response, ok := out.RawResponse.(*smithyhttp.Response) + if !ok { + return out, metadata, &smithy.DeserializationError{Err: fmt.Errorf("unknown transport type %T", out.RawResponse)} + } + + if response.StatusCode < 200 || response.StatusCode >= 300 { + return out, metadata, awsAwsjson11_deserializeOpErrorValidatePullThroughCacheRule(response, &metadata) + } + output := &ValidatePullThroughCacheRuleOutput{} + out.Result = output + var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) - body := io.TeeReader(errorBody, ringBuffer) + body := io.TeeReader(response.Body, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() var shape interface{} @@ -5067,12 +5016,10 @@ func awsAwsjson11_deserializeErrorImageDigestDoesNotMatchException(response *smi Err: fmt.Errorf("failed to decode response body, %w", err), Snapshot: snapshot.Bytes(), } - return err + return out, metadata, err } - output := &types.ImageDigestDoesNotMatchException{} - err := awsAwsjson11_deserializeDocumentImageDigestDoesNotMatchException(&output, shape) - + err = awsAwsjson11_deserializeOpDocumentValidatePullThroughCacheRuleOutput(&output, shape) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -5080,7 +5027,170 @@ func awsAwsjson11_deserializeErrorImageDigestDoesNotMatchException(response *smi Err: fmt.Errorf("failed to decode response body, %w", err), Snapshot: snapshot.Bytes(), } - return err + return out, metadata, err + } + + return out, metadata, err +} + +func awsAwsjson11_deserializeOpErrorValidatePullThroughCacheRule(response *smithyhttp.Response, metadata *middleware.Metadata) error { + var errorBuffer bytes.Buffer + if _, err := io.Copy(&errorBuffer, response.Body); err != nil { + return &smithy.DeserializationError{Err: fmt.Errorf("failed to copy error response body, %w", err)} + } + errorBody := bytes.NewReader(errorBuffer.Bytes()) + + errorCode := "UnknownError" + errorMessage := errorCode + + headerCode := response.Header.Get("X-Amzn-ErrorType") + + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + bodyInfo, err := getProtocolErrorInfo(decoder) + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) + } + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message + } + switch { + case strings.EqualFold("InvalidParameterException", errorCode): + return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) + + case strings.EqualFold("PullThroughCacheRuleNotFoundException", errorCode): + return awsAwsjson11_deserializeErrorPullThroughCacheRuleNotFoundException(response, errorBody) + + case strings.EqualFold("ServerException", errorCode): + return awsAwsjson11_deserializeErrorServerException(response, errorBody) + + case strings.EqualFold("ValidationException", errorCode): + return awsAwsjson11_deserializeErrorValidationException(response, errorBody) + + default: + genericError := &smithy.GenericAPIError{ + Code: errorCode, + Message: errorMessage, + } + return genericError + + } +} + +func awsAwsjson11_deserializeErrorEmptyUploadException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + output := &types.EmptyUploadException{} + err := awsAwsjson11_deserializeDocumentEmptyUploadException(&output, shape) + + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + return output +} + +func awsAwsjson11_deserializeErrorImageAlreadyExistsException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + output := &types.ImageAlreadyExistsException{} + err := awsAwsjson11_deserializeDocumentImageAlreadyExistsException(&output, shape) + + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + return output +} + +func awsAwsjson11_deserializeErrorImageDigestDoesNotMatchException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + output := &types.ImageDigestDoesNotMatchException{} + err := awsAwsjson11_deserializeDocumentImageDigestDoesNotMatchException(&output, shape) + + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err } errorBody.Seek(0, io.SeekStart) @@ -5735,8 +5845,183 @@ func awsAwsjson11_deserializeErrorRegistryPolicyNotFoundException(response *smit return err } - output := &types.RegistryPolicyNotFoundException{} - err := awsAwsjson11_deserializeDocumentRegistryPolicyNotFoundException(&output, shape) + output := &types.RegistryPolicyNotFoundException{} + err := awsAwsjson11_deserializeDocumentRegistryPolicyNotFoundException(&output, shape) + + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + return output +} + +func awsAwsjson11_deserializeErrorRepositoryAlreadyExistsException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + output := &types.RepositoryAlreadyExistsException{} + err := awsAwsjson11_deserializeDocumentRepositoryAlreadyExistsException(&output, shape) + + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + return output +} + +func awsAwsjson11_deserializeErrorRepositoryNotEmptyException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + output := &types.RepositoryNotEmptyException{} + err := awsAwsjson11_deserializeDocumentRepositoryNotEmptyException(&output, shape) + + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + return output +} + +func awsAwsjson11_deserializeErrorRepositoryNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + output := &types.RepositoryNotFoundException{} + err := awsAwsjson11_deserializeDocumentRepositoryNotFoundException(&output, shape) + + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + return output +} + +func awsAwsjson11_deserializeErrorRepositoryPolicyNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + output := &types.RepositoryPolicyNotFoundException{} + err := awsAwsjson11_deserializeDocumentRepositoryPolicyNotFoundException(&output, shape) + + if err != nil { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + errorBody.Seek(0, io.SeekStart) + return output +} + +func awsAwsjson11_deserializeErrorScanNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { + var buff [1024]byte + ringBuffer := smithyio.NewRingBuffer(buff[:]) + + body := io.TeeReader(errorBody, ringBuffer) + decoder := json.NewDecoder(body) + decoder.UseNumber() + var shape interface{} + if err := decoder.Decode(&shape); err != nil && err != io.EOF { + var snapshot bytes.Buffer + io.Copy(&snapshot, ringBuffer) + err = &smithy.DeserializationError{ + Err: fmt.Errorf("failed to decode response body, %w", err), + Snapshot: snapshot.Bytes(), + } + return err + } + + output := &types.ScanNotFoundException{} + err := awsAwsjson11_deserializeDocumentScanNotFoundException(&output, shape) if err != nil { var snapshot bytes.Buffer @@ -5752,7 +6037,7 @@ func awsAwsjson11_deserializeErrorRegistryPolicyNotFoundException(response *smit return output } -func awsAwsjson11_deserializeErrorRepositoryAlreadyExistsException(response *smithyhttp.Response, errorBody *bytes.Reader) error { +func awsAwsjson11_deserializeErrorSecretNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -5770,8 +6055,8 @@ func awsAwsjson11_deserializeErrorRepositoryAlreadyExistsException(response *smi return err } - output := &types.RepositoryAlreadyExistsException{} - err := awsAwsjson11_deserializeDocumentRepositoryAlreadyExistsException(&output, shape) + output := &types.SecretNotFoundException{} + err := awsAwsjson11_deserializeDocumentSecretNotFoundException(&output, shape) if err != nil { var snapshot bytes.Buffer @@ -5787,7 +6072,7 @@ func awsAwsjson11_deserializeErrorRepositoryAlreadyExistsException(response *smi return output } -func awsAwsjson11_deserializeErrorRepositoryNotEmptyException(response *smithyhttp.Response, errorBody *bytes.Reader) error { +func awsAwsjson11_deserializeErrorServerException(response *smithyhttp.Response, errorBody *bytes.Reader) error { var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -5805,8 +6090,8 @@ func awsAwsjson11_deserializeErrorRepositoryNotEmptyException(response *smithyht return err } - output := &types.RepositoryNotEmptyException{} - err := awsAwsjson11_deserializeDocumentRepositoryNotEmptyException(&output, shape) + output := &types.ServerException{} + err := awsAwsjson11_deserializeDocumentServerException(&output, shape) if err != nil { var snapshot bytes.Buffer @@ -5822,7 +6107,7 @@ func awsAwsjson11_deserializeErrorRepositoryNotEmptyException(response *smithyht return output } -func awsAwsjson11_deserializeErrorRepositoryNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { +func awsAwsjson11_deserializeErrorTooManyTagsException(response *smithyhttp.Response, errorBody *bytes.Reader) error { var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -5840,8 +6125,8 @@ func awsAwsjson11_deserializeErrorRepositoryNotFoundException(response *smithyht return err } - output := &types.RepositoryNotFoundException{} - err := awsAwsjson11_deserializeDocumentRepositoryNotFoundException(&output, shape) + output := &types.TooManyTagsException{} + err := awsAwsjson11_deserializeDocumentTooManyTagsException(&output, shape) if err != nil { var snapshot bytes.Buffer @@ -5857,7 +6142,7 @@ func awsAwsjson11_deserializeErrorRepositoryNotFoundException(response *smithyht return output } -func awsAwsjson11_deserializeErrorRepositoryPolicyNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { +func awsAwsjson11_deserializeErrorUnableToAccessSecretException(response *smithyhttp.Response, errorBody *bytes.Reader) error { var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -5875,8 +6160,8 @@ func awsAwsjson11_deserializeErrorRepositoryPolicyNotFoundException(response *sm return err } - output := &types.RepositoryPolicyNotFoundException{} - err := awsAwsjson11_deserializeDocumentRepositoryPolicyNotFoundException(&output, shape) + output := &types.UnableToAccessSecretException{} + err := awsAwsjson11_deserializeDocumentUnableToAccessSecretException(&output, shape) if err != nil { var snapshot bytes.Buffer @@ -5892,7 +6177,7 @@ func awsAwsjson11_deserializeErrorRepositoryPolicyNotFoundException(response *sm return output } -func awsAwsjson11_deserializeErrorScanNotFoundException(response *smithyhttp.Response, errorBody *bytes.Reader) error { +func awsAwsjson11_deserializeErrorUnableToDecryptSecretValueException(response *smithyhttp.Response, errorBody *bytes.Reader) error { var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -5910,8 +6195,8 @@ func awsAwsjson11_deserializeErrorScanNotFoundException(response *smithyhttp.Res return err } - output := &types.ScanNotFoundException{} - err := awsAwsjson11_deserializeDocumentScanNotFoundException(&output, shape) + output := &types.UnableToDecryptSecretValueException{} + err := awsAwsjson11_deserializeDocumentUnableToDecryptSecretValueException(&output, shape) if err != nil { var snapshot bytes.Buffer @@ -5927,7 +6212,7 @@ func awsAwsjson11_deserializeErrorScanNotFoundException(response *smithyhttp.Res return output } -func awsAwsjson11_deserializeErrorServerException(response *smithyhttp.Response, errorBody *bytes.Reader) error { +func awsAwsjson11_deserializeErrorUnableToGetUpstreamImageException(response *smithyhttp.Response, errorBody *bytes.Reader) error { var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -5945,8 +6230,8 @@ func awsAwsjson11_deserializeErrorServerException(response *smithyhttp.Response, return err } - output := &types.ServerException{} - err := awsAwsjson11_deserializeDocumentServerException(&output, shape) + output := &types.UnableToGetUpstreamImageException{} + err := awsAwsjson11_deserializeDocumentUnableToGetUpstreamImageException(&output, shape) if err != nil { var snapshot bytes.Buffer @@ -5962,7 +6247,7 @@ func awsAwsjson11_deserializeErrorServerException(response *smithyhttp.Response, return output } -func awsAwsjson11_deserializeErrorTooManyTagsException(response *smithyhttp.Response, errorBody *bytes.Reader) error { +func awsAwsjson11_deserializeErrorUnableToGetUpstreamLayerException(response *smithyhttp.Response, errorBody *bytes.Reader) error { var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -5980,8 +6265,8 @@ func awsAwsjson11_deserializeErrorTooManyTagsException(response *smithyhttp.Resp return err } - output := &types.TooManyTagsException{} - err := awsAwsjson11_deserializeDocumentTooManyTagsException(&output, shape) + output := &types.UnableToGetUpstreamLayerException{} + err := awsAwsjson11_deserializeDocumentUnableToGetUpstreamLayerException(&output, shape) if err != nil { var snapshot bytes.Buffer @@ -9331,6 +9616,15 @@ func awsAwsjson11_deserializeDocumentPullThroughCacheRule(v **types.PullThroughC } } + case "credentialArn": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected CredentialArn to be of type string, got %T instead", value) + } + sv.CredentialArn = ptr.String(jtv) + } + case "ecrRepositoryPrefix": if value != nil { jtv, ok := value.(string) @@ -9349,6 +9643,31 @@ func awsAwsjson11_deserializeDocumentPullThroughCacheRule(v **types.PullThroughC sv.RegistryId = ptr.String(jtv) } + case "updatedAt": + if value != nil { + switch jtv := value.(type) { + case json.Number: + f64, err := jtv.Float64() + if err != nil { + return err + } + sv.UpdatedAt = ptr.Time(smithytime.ParseEpochSeconds(f64)) + + default: + return fmt.Errorf("expected UpdatedTimestamp to be a JSON Number, got %T instead", value) + + } + } + + case "upstreamRegistry": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected UpstreamRegistry to be of type string, got %T instead", value) + } + sv.UpstreamRegistry = types.UpstreamRegistry(jtv) + } + case "upstreamRegistryUrl": if value != nil { jtv, ok := value.(string) @@ -10895,13 +11214,212 @@ func awsAwsjson11_deserializeDocumentScoreDetails(v **types.ScoreDetails, value default: _, _ = key, value - } + } + } + *v = sv + return nil +} + +func awsAwsjson11_deserializeDocumentSecretNotFoundException(v **types.SecretNotFoundException, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.SecretNotFoundException + if *v == nil { + sv = &types.SecretNotFoundException{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "message": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected ExceptionMessage to be of type string, got %T instead", value) + } + sv.Message = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson11_deserializeDocumentServerException(v **types.ServerException, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.ServerException + if *v == nil { + sv = &types.ServerException{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "message": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected ExceptionMessage to be of type string, got %T instead", value) + } + sv.Message = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson11_deserializeDocumentTag(v **types.Tag, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *types.Tag + if *v == nil { + sv = &types.Tag{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "Key": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected TagKey to be of type string, got %T instead", value) + } + sv.Key = ptr.String(jtv) + } + + case "Value": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected TagValue to be of type string, got %T instead", value) + } + sv.Value = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +func awsAwsjson11_deserializeDocumentTagList(v *[]types.Tag, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.([]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var cv []types.Tag + if *v == nil { + cv = []types.Tag{} + } else { + cv = *v + } + + for _, value := range shape { + var col types.Tag + destAddr := &col + if err := awsAwsjson11_deserializeDocumentTag(&destAddr, value); err != nil { + return err + } + col = *destAddr + cv = append(cv, col) + + } + *v = cv + return nil +} + +func awsAwsjson11_deserializeDocumentTags(v *map[string]string, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var mv map[string]string + if *v == nil { + mv = map[string]string{} + } else { + mv = *v + } + + for key, value := range shape { + var parsedVal string + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected TagValue to be of type string, got %T instead", value) + } + parsedVal = jtv + } + mv[key] = parsedVal + } - *v = sv + *v = mv return nil } -func awsAwsjson11_deserializeDocumentServerException(v **types.ServerException, value interface{}) error { +func awsAwsjson11_deserializeDocumentTooManyTagsException(v **types.TooManyTagsException, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) } @@ -10914,9 +11432,9 @@ func awsAwsjson11_deserializeDocumentServerException(v **types.ServerException, return fmt.Errorf("unexpected JSON type %v", value) } - var sv *types.ServerException + var sv *types.TooManyTagsException if *v == nil { - sv = &types.ServerException{} + sv = &types.TooManyTagsException{} } else { sv = *v } @@ -10941,7 +11459,7 @@ func awsAwsjson11_deserializeDocumentServerException(v **types.ServerException, return nil } -func awsAwsjson11_deserializeDocumentTag(v **types.Tag, value interface{}) error { +func awsAwsjson11_deserializeDocumentUnableToAccessSecretException(v **types.UnableToAccessSecretException, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) } @@ -10954,31 +11472,22 @@ func awsAwsjson11_deserializeDocumentTag(v **types.Tag, value interface{}) error return fmt.Errorf("unexpected JSON type %v", value) } - var sv *types.Tag + var sv *types.UnableToAccessSecretException if *v == nil { - sv = &types.Tag{} + sv = &types.UnableToAccessSecretException{} } else { sv = *v } for key, value := range shape { switch key { - case "Key": - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TagKey to be of type string, got %T instead", value) - } - sv.Key = ptr.String(jtv) - } - - case "Value": + case "message": if value != nil { jtv, ok := value.(string) if !ok { - return fmt.Errorf("expected TagValue to be of type string, got %T instead", value) + return fmt.Errorf("expected ExceptionMessage to be of type string, got %T instead", value) } - sv.Value = ptr.String(jtv) + sv.Message = ptr.String(jtv) } default: @@ -10990,7 +11499,7 @@ func awsAwsjson11_deserializeDocumentTag(v **types.Tag, value interface{}) error return nil } -func awsAwsjson11_deserializeDocumentTagList(v *[]types.Tag, value interface{}) error { +func awsAwsjson11_deserializeDocumentUnableToDecryptSecretValueException(v **types.UnableToDecryptSecretValueException, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) } @@ -10998,33 +11507,39 @@ func awsAwsjson11_deserializeDocumentTagList(v *[]types.Tag, value interface{}) return nil } - shape, ok := value.([]interface{}) + shape, ok := value.(map[string]interface{}) if !ok { return fmt.Errorf("unexpected JSON type %v", value) } - var cv []types.Tag + var sv *types.UnableToDecryptSecretValueException if *v == nil { - cv = []types.Tag{} + sv = &types.UnableToDecryptSecretValueException{} } else { - cv = *v + sv = *v } - for _, value := range shape { - var col types.Tag - destAddr := &col - if err := awsAwsjson11_deserializeDocumentTag(&destAddr, value); err != nil { - return err - } - col = *destAddr - cv = append(cv, col) + for key, value := range shape { + switch key { + case "message": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected ExceptionMessage to be of type string, got %T instead", value) + } + sv.Message = ptr.String(jtv) + } + default: + _, _ = key, value + + } } - *v = cv + *v = sv return nil } -func awsAwsjson11_deserializeDocumentTags(v *map[string]string, value interface{}) error { +func awsAwsjson11_deserializeDocumentUnableToGetUpstreamImageException(v **types.UnableToGetUpstreamImageException, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) } @@ -11037,30 +11552,34 @@ func awsAwsjson11_deserializeDocumentTags(v *map[string]string, value interface{ return fmt.Errorf("unexpected JSON type %v", value) } - var mv map[string]string + var sv *types.UnableToGetUpstreamImageException if *v == nil { - mv = map[string]string{} + sv = &types.UnableToGetUpstreamImageException{} } else { - mv = *v + sv = *v } for key, value := range shape { - var parsedVal string - if value != nil { - jtv, ok := value.(string) - if !ok { - return fmt.Errorf("expected TagValue to be of type string, got %T instead", value) + switch key { + case "message": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected ExceptionMessage to be of type string, got %T instead", value) + } + sv.Message = ptr.String(jtv) } - parsedVal = jtv - } - mv[key] = parsedVal + default: + _, _ = key, value + + } } - *v = mv + *v = sv return nil } -func awsAwsjson11_deserializeDocumentTooManyTagsException(v **types.TooManyTagsException, value interface{}) error { +func awsAwsjson11_deserializeDocumentUnableToGetUpstreamLayerException(v **types.UnableToGetUpstreamLayerException, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) } @@ -11073,9 +11592,9 @@ func awsAwsjson11_deserializeDocumentTooManyTagsException(v **types.TooManyTagsE return fmt.Errorf("unexpected JSON type %v", value) } - var sv *types.TooManyTagsException + var sv *types.UnableToGetUpstreamLayerException if *v == nil { - sv = &types.TooManyTagsException{} + sv = &types.UnableToGetUpstreamLayerException{} } else { sv = *v } @@ -11670,6 +12189,15 @@ func awsAwsjson11_deserializeOpDocumentCreatePullThroughCacheRuleOutput(v **Crea } } + case "credentialArn": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected CredentialArn to be of type string, got %T instead", value) + } + sv.CredentialArn = ptr.String(jtv) + } + case "ecrRepositoryPrefix": if value != nil { jtv, ok := value.(string) @@ -11688,6 +12216,15 @@ func awsAwsjson11_deserializeOpDocumentCreatePullThroughCacheRuleOutput(v **Crea sv.RegistryId = ptr.String(jtv) } + case "upstreamRegistry": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected UpstreamRegistry to be of type string, got %T instead", value) + } + sv.UpstreamRegistry = types.UpstreamRegistry(jtv) + } + case "upstreamRegistryUrl": if value != nil { jtv, ok := value.(string) @@ -11854,6 +12391,15 @@ func awsAwsjson11_deserializeOpDocumentDeletePullThroughCacheRuleOutput(v **Dele } } + case "credentialArn": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected CredentialArn to be of type string, got %T instead", value) + } + sv.CredentialArn = ptr.String(jtv) + } + case "ecrRepositoryPrefix": if value != nil { jtv, ok := value.(string) @@ -13440,6 +13986,80 @@ func awsAwsjson11_deserializeOpDocumentUntagResourceOutput(v **UntagResourceOutp return nil } +func awsAwsjson11_deserializeOpDocumentUpdatePullThroughCacheRuleOutput(v **UpdatePullThroughCacheRuleOutput, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *UpdatePullThroughCacheRuleOutput + if *v == nil { + sv = &UpdatePullThroughCacheRuleOutput{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "credentialArn": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected CredentialArn to be of type string, got %T instead", value) + } + sv.CredentialArn = ptr.String(jtv) + } + + case "ecrRepositoryPrefix": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected PullThroughCacheRuleRepositoryPrefix to be of type string, got %T instead", value) + } + sv.EcrRepositoryPrefix = ptr.String(jtv) + } + + case "registryId": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected RegistryId to be of type string, got %T instead", value) + } + sv.RegistryId = ptr.String(jtv) + } + + case "updatedAt": + if value != nil { + switch jtv := value.(type) { + case json.Number: + f64, err := jtv.Float64() + if err != nil { + return err + } + sv.UpdatedAt = ptr.Time(smithytime.ParseEpochSeconds(f64)) + + default: + return fmt.Errorf("expected UpdatedTimestamp to be a JSON Number, got %T instead", value) + + } + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + func awsAwsjson11_deserializeOpDocumentUploadLayerPartOutput(v **UploadLayerPartOutput, value interface{}) error { if v == nil { return fmt.Errorf("unexpected nil of type %T", v) @@ -13510,3 +14130,117 @@ func awsAwsjson11_deserializeOpDocumentUploadLayerPartOutput(v **UploadLayerPart *v = sv return nil } + +func awsAwsjson11_deserializeOpDocumentValidatePullThroughCacheRuleOutput(v **ValidatePullThroughCacheRuleOutput, value interface{}) error { + if v == nil { + return fmt.Errorf("unexpected nil of type %T", v) + } + if value == nil { + return nil + } + + shape, ok := value.(map[string]interface{}) + if !ok { + return fmt.Errorf("unexpected JSON type %v", value) + } + + var sv *ValidatePullThroughCacheRuleOutput + if *v == nil { + sv = &ValidatePullThroughCacheRuleOutput{} + } else { + sv = *v + } + + for key, value := range shape { + switch key { + case "credentialArn": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected CredentialArn to be of type string, got %T instead", value) + } + sv.CredentialArn = ptr.String(jtv) + } + + case "ecrRepositoryPrefix": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected PullThroughCacheRuleRepositoryPrefix to be of type string, got %T instead", value) + } + sv.EcrRepositoryPrefix = ptr.String(jtv) + } + + case "failure": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected PTCValidateFailure to be of type string, got %T instead", value) + } + sv.Failure = ptr.String(jtv) + } + + case "isValid": + if value != nil { + jtv, ok := value.(bool) + if !ok { + return fmt.Errorf("expected IsPTCRuleValid to be of type *bool, got %T instead", value) + } + sv.IsValid = jtv + } + + case "registryId": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected RegistryId to be of type string, got %T instead", value) + } + sv.RegistryId = ptr.String(jtv) + } + + case "upstreamRegistryUrl": + if value != nil { + jtv, ok := value.(string) + if !ok { + return fmt.Errorf("expected Url to be of type string, got %T instead", value) + } + sv.UpstreamRegistryUrl = ptr.String(jtv) + } + + default: + _, _ = key, value + + } + } + *v = sv + return nil +} + +type protocolErrorInfo struct { + Type string `json:"__type"` + Message string + Code any // nonstandard for awsjson but some services do present the type here +} + +func getProtocolErrorInfo(decoder *json.Decoder) (protocolErrorInfo, error) { + var errInfo protocolErrorInfo + if err := decoder.Decode(&errInfo); err != nil { + if err == io.EOF { + return errInfo, nil + } + return errInfo, err + } + + return errInfo, nil +} + +func resolveProtocolErrorType(headerType string, bodyInfo protocolErrorInfo) (string, bool) { + if len(headerType) != 0 { + return headerType, true + } else if len(bodyInfo.Type) != 0 { + return bodyInfo.Type, true + } else if code, ok := bodyInfo.Code.(string); ok && len(code) != 0 { + return code, true + } + return "", false +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/endpoints.go index e255bc9d524..0cf591df272 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/endpoints.go @@ -8,10 +8,18 @@ import ( "fmt" "github.com/aws/aws-sdk-go-v2/aws" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" + "github.com/aws/aws-sdk-go-v2/internal/endpoints" + "github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn" internalendpoints "github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints" + smithyauth "github.com/aws/smithy-go/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" smithyhttp "github.com/aws/smithy-go/transport/http" + "net/http" "net/url" + "os" "strings" ) @@ -39,13 +47,6 @@ func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointRe return fn(region, options) } -func resolveDefaultEndpointConfiguration(o *Options) { - if o.EndpointResolver != nil { - return - } - o.EndpointResolver = NewDefaultEndpointResolver() -} - // EndpointResolverFromURL returns an EndpointResolver configured using the // provided endpoint url. By default, the resolved endpoint resolver uses the // client region as signing region, and the endpoint source is set to @@ -79,6 +80,10 @@ func (*ResolveEndpoint) ID() string { func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( out middleware.SerializeOutput, metadata middleware.Metadata, err error, ) { + if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) { + return next.HandleSerialize(ctx, in) + } + req, ok := in.Request.(*smithyhttp.Request) if !ok { return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) @@ -94,6 +99,11 @@ func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.Ser var endpoint aws.Endpoint endpoint, err = m.Resolver.ResolveEndpoint(awsmiddleware.GetRegion(ctx), eo) if err != nil { + nf := (&aws.EndpointNotFoundError{}) + if errors.As(err, &nf) { + ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, false) + return next.HandleSerialize(ctx, in) + } return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) } @@ -129,27 +139,10 @@ func removeResolveEndpointMiddleware(stack *middleware.Stack) error { type wrappedEndpointResolver struct { awsResolver aws.EndpointResolverWithOptions - resolver EndpointResolver } func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - if w.awsResolver == nil { - goto fallback - } - endpoint, err = w.awsResolver.ResolveEndpoint(ServiceID, region, options) - if err == nil { - return endpoint, nil - } - - if nf := (&aws.EndpointNotFoundError{}); !errors.As(err, &nf) { - return endpoint, err - } - -fallback: - if w.resolver == nil { - return endpoint, fmt.Errorf("default endpoint resolver provided was nil") - } - return w.resolver.ResolveEndpoint(region, options) + return w.awsResolver.ResolveEndpoint(ServiceID, region, options) } type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error) @@ -160,12 +153,13 @@ func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, opti var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil) -// withEndpointResolver returns an EndpointResolver that first delegates endpoint resolution to the awsResolver. -// If awsResolver returns aws.EndpointNotFoundError error, the resolver will use the the provided -// fallbackResolver for resolution. +// withEndpointResolver returns an aws.EndpointResolverWithOptions that first delegates endpoint resolution to the awsResolver. +// If awsResolver returns aws.EndpointNotFoundError error, the v1 resolver middleware will swallow the error, +// and set an appropriate context flag such that fallback will occur when EndpointResolverV2 is invoked +// via its middleware. // -// fallbackResolver must not be nil -func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions, fallbackResolver EndpointResolver) EndpointResolver { +// If another error (besides aws.EndpointNotFoundError) is returned, then that error will be propagated. +func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions) EndpointResolver { var resolver aws.EndpointResolverWithOptions if awsResolverWithOptions != nil { @@ -176,7 +170,6 @@ func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptio return &wrappedEndpointResolver{ awsResolver: resolver, - resolver: fallbackResolver, } } @@ -198,3 +191,364 @@ func finalizeClientEndpointResolverOptions(options *Options) { } } + +func resolveEndpointResolverV2(options *Options) { + if options.EndpointResolverV2 == nil { + options.EndpointResolverV2 = NewDefaultEndpointResolverV2() + } +} + +func resolveBaseEndpoint(cfg aws.Config, o *Options) { + if cfg.BaseEndpoint != nil { + o.BaseEndpoint = cfg.BaseEndpoint + } + + _, g := os.LookupEnv("AWS_ENDPOINT_URL") + _, s := os.LookupEnv("AWS_ENDPOINT_URL_ECR") + + if g && !s { + return + } + + value, found, err := internalConfig.ResolveServiceBaseEndpoint(context.Background(), "ECR", cfg.ConfigSources) + if found && err == nil { + o.BaseEndpoint = &value + } +} + +func bindRegion(region string) *string { + if region == "" { + return nil + } + return aws.String(endpoints.MapFIPSRegion(region)) +} + +// EndpointParameters provides the parameters that influence how endpoints are +// resolved. +type EndpointParameters struct { + // The AWS region used to dispatch the request. + // + // Parameter is + // required. + // + // AWS::Region + Region *string + + // When true, use the dual-stack endpoint. If the configured endpoint does not + // support dual-stack, dispatching the request MAY return an error. + // + // Defaults to + // false if no value is provided. + // + // AWS::UseDualStack + UseDualStack *bool + + // When true, send this request to the FIPS-compliant regional endpoint. If the + // configured endpoint does not have a FIPS compliant endpoint, dispatching the + // request will return an error. + // + // Defaults to false if no value is + // provided. + // + // AWS::UseFIPS + UseFIPS *bool + + // Override the endpoint used to send this request + // + // Parameter is + // required. + // + // SDK::Endpoint + Endpoint *string +} + +// ValidateRequired validates required parameters are set. +func (p EndpointParameters) ValidateRequired() error { + if p.UseDualStack == nil { + return fmt.Errorf("parameter UseDualStack is required") + } + + if p.UseFIPS == nil { + return fmt.Errorf("parameter UseFIPS is required") + } + + return nil +} + +// WithDefaults returns a shallow copy of EndpointParameterswith default values +// applied to members where applicable. +func (p EndpointParameters) WithDefaults() EndpointParameters { + if p.UseDualStack == nil { + p.UseDualStack = ptr.Bool(false) + } + + if p.UseFIPS == nil { + p.UseFIPS = ptr.Bool(false) + } + return p +} + +// EndpointResolverV2 provides the interface for resolving service endpoints. +type EndpointResolverV2 interface { + // ResolveEndpoint attempts to resolve the endpoint with the provided options, + // returning the endpoint if found. Otherwise an error is returned. + ResolveEndpoint(ctx context.Context, params EndpointParameters) ( + smithyendpoints.Endpoint, error, + ) +} + +// resolver provides the implementation for resolving endpoints. +type resolver struct{} + +func NewDefaultEndpointResolverV2() EndpointResolverV2 { + return &resolver{} +} + +// ResolveEndpoint attempts to resolve the endpoint with the provided options, +// returning the endpoint if found. Otherwise an error is returned. +func (r *resolver) ResolveEndpoint( + ctx context.Context, params EndpointParameters, +) ( + endpoint smithyendpoints.Endpoint, err error, +) { + params = params.WithDefaults() + if err = params.ValidateRequired(); err != nil { + return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err) + } + _UseDualStack := *params.UseDualStack + _UseFIPS := *params.UseFIPS + + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if _UseFIPS == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: FIPS and custom endpoint are not supported") + } + if _UseDualStack == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Dualstack and custom endpoint are not supported") + } + uriString := _Endpoint + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + if exprVal := params.Region; exprVal != nil { + _Region := *exprVal + _ = _Region + if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { + _PartitionResult := *exprVal + _ = _PartitionResult + if _UseFIPS == true { + if _UseDualStack == true { + if true == _PartitionResult.SupportsFIPS { + if true == _PartitionResult.SupportsDualStack { + uriString := func() string { + var out strings.Builder + out.WriteString("https://api.ecr-fips.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_PartitionResult.DualStackDnsSuffix) + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS and DualStack are enabled, but this partition does not support one or both") + } + } + if _UseFIPS == true { + if _PartitionResult.SupportsFIPS == true { + if _PartitionResult.Name == "aws" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://ecr-fips.") + out.WriteString(_Region) + out.WriteString(".amazonaws.com") + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + if _PartitionResult.Name == "aws-us-gov" { + uriString := func() string { + var out strings.Builder + out.WriteString("https://ecr-fips.") + out.WriteString(_Region) + out.WriteString(".amazonaws.com") + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + uriString := func() string { + var out strings.Builder + out.WriteString("https://api.ecr-fips.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_PartitionResult.DnsSuffix) + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS is enabled but this partition does not support FIPS") + } + if _UseDualStack == true { + if true == _PartitionResult.SupportsDualStack { + uriString := func() string { + var out strings.Builder + out.WriteString("https://api.ecr.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_PartitionResult.DualStackDnsSuffix) + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "DualStack is enabled but this partition does not support DualStack") + } + uriString := func() string { + var out strings.Builder + out.WriteString("https://api.ecr.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_PartitionResult.DnsSuffix) + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Missing Region") +} + +type endpointParamsBinder interface { + bindEndpointParams(*EndpointParameters) +} + +func bindEndpointParams(input interface{}, options Options) *EndpointParameters { + params := &EndpointParameters{} + + params.Region = bindRegion(options.Region) + params.UseDualStack = aws.Bool(options.EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled) + params.UseFIPS = aws.Bool(options.EndpointOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled) + params.Endpoint = options.BaseEndpoint + + if b, ok := input.(endpointParamsBinder); ok { + b.bindEndpointParams(params) + } + + return params +} + +type resolveEndpointV2Middleware struct { + options Options +} + +func (*resolveEndpointV2Middleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + if awsmiddleware.GetRequiresLegacyEndpoints(ctx) { + return next.HandleFinalize(ctx, in) + } + + req, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.options.EndpointResolverV2 == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := bindEndpointParams(getOperationInput(ctx), m.options) + endpt, err := m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + if endpt.URI.RawPath == "" && req.URL.RawPath != "" { + endpt.URI.RawPath = endpt.URI.Path + } + req.URL.Scheme = endpt.URI.Scheme + req.URL.Host = endpt.URI.Host + req.URL.Path = smithyhttp.JoinPath(endpt.URI.Path, req.URL.Path) + req.URL.RawPath = smithyhttp.JoinPath(endpt.URI.RawPath, req.URL.RawPath) + for k := range endpt.Headers { + req.Header.Set(k, endpt.Headers.Get(k)) + } + + rscheme := getResolvedAuthScheme(ctx) + if rscheme == nil { + return out, metadata, fmt.Errorf("no resolved auth scheme") + } + + opts, _ := smithyauth.GetAuthOptions(&endpt.Properties) + for _, o := range opts { + rscheme.SignerProperties.SetAll(&o.SignerProperties) + } + + return next.HandleFinalize(ctx, in) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/generated.json index 631a65bbaf8..2e7e94262bf 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/generated.json @@ -49,15 +49,22 @@ "api_op_StartLifecyclePolicyPreview.go", "api_op_TagResource.go", "api_op_UntagResource.go", + "api_op_UpdatePullThroughCacheRule.go", "api_op_UploadLayerPart.go", + "api_op_ValidatePullThroughCacheRule.go", + "auth.go", "deserializers.go", "doc.go", "endpoints.go", + "endpoints_config_test.go", + "endpoints_test.go", "generated.json", "internal/endpoints/endpoints.go", "internal/endpoints/endpoints_test.go", + "options.go", "protocol_test.go", "serializers.go", + "snapshot_test.go", "types/enums.go", "types/errors.go", "types/types.go", diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/go_module_metadata.go index 0e83ac5d005..8dde998fa92 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/go_module_metadata.go @@ -3,4 +3,4 @@ package ecr // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.18.11" +const goModuleVersion = "1.27.3" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints/endpoints.go index e2a8a780640..48d24a1e80b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints/endpoints.go @@ -90,14 +90,16 @@ var partitionRegexp = struct { AwsIso *regexp.Regexp AwsIsoB *regexp.Regexp AwsIsoE *regexp.Regexp + AwsIsoF *regexp.Regexp AwsUsGov *regexp.Regexp }{ - Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af)\\-\\w+\\-\\d+$"), + Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il)\\-\\w+\\-\\d+$"), AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"), AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"), AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"), AwsIsoE: regexp.MustCompile("^eu\\-isoe\\-\\w+\\-\\d+$"), + AwsIsoF: regexp.MustCompile("^us\\-isof\\-\\w+\\-\\d+$"), AwsUsGov: regexp.MustCompile("^us\\-gov\\-\\w+\\-\\d+$"), } @@ -233,6 +235,14 @@ var defaultPartitions = endpoints.Partitions{ Region: "ca-central-1", }, }, + endpoints.EndpointKey{ + Region: "ca-west-1", + }: endpoints.Endpoint{ + Hostname: "api.ecr.ca-west-1.amazonaws.com", + CredentialScope: endpoints.CredentialScope{ + Region: "ca-west-1", + }, + }, endpoints.EndpointKey{ Region: "dkr-us-east-1", }: endpoints.Endpoint{ @@ -441,6 +451,14 @@ var defaultPartitions = endpoints.Partitions{ }, Deprecated: aws.TrueTernary, }, + endpoints.EndpointKey{ + Region: "il-central-1", + }: endpoints.Endpoint{ + Hostname: "api.ecr.il-central-1.amazonaws.com", + CredentialScope: endpoints.CredentialScope{ + Region: "il-central-1", + }, + }, endpoints.EndpointKey{ Region: "me-central-1", }: endpoints.Endpoint{ @@ -679,6 +697,27 @@ var defaultPartitions = endpoints.Partitions{ RegionRegex: partitionRegexp.AwsIsoE, IsRegionalized: true, }, + { + ID: "aws-iso-f", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "api.ecr-fips.{region}.csp.hci.ic.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "api.ecr.{region}.csp.hci.ic.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + RegionRegex: partitionRegexp.AwsIsoF, + IsRegionalized: true, + }, { ID: "aws-us-gov", Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/options.go new file mode 100644 index 00000000000..0de783e381c --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/options.go @@ -0,0 +1,217 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package ecr + +import ( + "context" + "github.com/aws/aws-sdk-go-v2/aws" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" + smithyauth "github.com/aws/smithy-go/auth" + "github.com/aws/smithy-go/logging" + "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" + "net/http" +) + +type HTTPClient interface { + Do(*http.Request) (*http.Response, error) +} + +type Options struct { + // Set of options to modify how an operation is invoked. These apply to all + // operations invoked for this client. Use functional options on operation call to + // modify this list for per operation behavior. + APIOptions []func(*middleware.Stack) error + + // The optional application specific identifier appended to the User-Agent header. + AppID string + + // This endpoint will be given as input to an EndpointResolverV2. It is used for + // providing a custom base endpoint that is subject to modifications by the + // processing EndpointResolverV2. + BaseEndpoint *string + + // Configures the events that will be sent to the configured logger. + ClientLogMode aws.ClientLogMode + + // The credentials object to use when signing requests. + Credentials aws.CredentialsProvider + + // The configuration DefaultsMode that the SDK should use when constructing the + // clients initial default settings. + DefaultsMode aws.DefaultsMode + + // The endpoint options to be used when attempting to resolve an endpoint. + EndpointOptions EndpointResolverOptions + + // The service endpoint resolver. + // + // Deprecated: Deprecated: EndpointResolver and WithEndpointResolver. Providing a + // value for this field will likely prevent you from using any endpoint-related + // service features released after the introduction of EndpointResolverV2 and + // BaseEndpoint. To migrate an EndpointResolver implementation that uses a custom + // endpoint, set the client option BaseEndpoint instead. + EndpointResolver EndpointResolver + + // Resolves the endpoint used for a particular service operation. This should be + // used over the deprecated EndpointResolver. + EndpointResolverV2 EndpointResolverV2 + + // Signature Version 4 (SigV4) Signer + HTTPSignerV4 HTTPSignerV4 + + // The logger writer interface to write logging messages to. + Logger logging.Logger + + // The region to send requests to. (Required) + Region string + + // RetryMaxAttempts specifies the maximum number attempts an API client will call + // an operation that fails with a retryable error. A value of 0 is ignored, and + // will not be used to configure the API client created default retryer, or modify + // per operation call's retry max attempts. If specified in an operation call's + // functional options with a value that is different than the constructed client's + // Options, the Client's Retryer will be wrapped to use the operation's specific + // RetryMaxAttempts value. + RetryMaxAttempts int + + // RetryMode specifies the retry mode the API client will be created with, if + // Retryer option is not also specified. When creating a new API Clients this + // member will only be used if the Retryer Options member is nil. This value will + // be ignored if Retryer is not nil. Currently does not support per operation call + // overrides, may in the future. + RetryMode aws.RetryMode + + // Retryer guides how HTTP requests should be retried in case of recoverable + // failures. When nil the API client will use a default retryer. The kind of + // default retry created by the API client can be changed with the RetryMode + // option. + Retryer aws.Retryer + + // The RuntimeEnvironment configuration, only populated if the DefaultsMode is set + // to DefaultsModeAuto and is initialized using config.LoadDefaultConfig . You + // should not populate this structure programmatically, or rely on the values here + // within your applications. + RuntimeEnvironment aws.RuntimeEnvironment + + // The initial DefaultsMode used when the client options were constructed. If the + // DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved + // value was at that point in time. Currently does not support per operation call + // overrides, may in the future. + resolvedDefaultsMode aws.DefaultsMode + + // The HTTP client to invoke API calls with. Defaults to client's default HTTP + // implementation if nil. + HTTPClient HTTPClient + + // The auth scheme resolver which determines how to authenticate for each + // operation. + AuthSchemeResolver AuthSchemeResolver + + // The list of auth schemes supported by the client. + AuthSchemes []smithyhttp.AuthScheme +} + +// Copy creates a clone where the APIOptions list is deep copied. +func (o Options) Copy() Options { + to := o + to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) + copy(to.APIOptions, o.APIOptions) + + return to +} + +func (o Options) GetIdentityResolver(schemeID string) smithyauth.IdentityResolver { + if schemeID == "aws.auth#sigv4" { + return getSigV4IdentityResolver(o) + } + if schemeID == "smithy.api#noAuth" { + return &smithyauth.AnonymousIdentityResolver{} + } + return nil +} + +// WithAPIOptions returns a functional option for setting the Client's APIOptions +// option. +func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { + return func(o *Options) { + o.APIOptions = append(o.APIOptions, optFns...) + } +} + +// Deprecated: EndpointResolver and WithEndpointResolver. Providing a value for +// this field will likely prevent you from using any endpoint-related service +// features released after the introduction of EndpointResolverV2 and BaseEndpoint. +// To migrate an EndpointResolver implementation that uses a custom endpoint, set +// the client option BaseEndpoint instead. +func WithEndpointResolver(v EndpointResolver) func(*Options) { + return func(o *Options) { + o.EndpointResolver = v + } +} + +// WithEndpointResolverV2 returns a functional option for setting the Client's +// EndpointResolverV2 option. +func WithEndpointResolverV2(v EndpointResolverV2) func(*Options) { + return func(o *Options) { + o.EndpointResolverV2 = v + } +} + +func getSigV4IdentityResolver(o Options) smithyauth.IdentityResolver { + if o.Credentials != nil { + return &internalauthsmithy.CredentialsProviderAdapter{Provider: o.Credentials} + } + return nil +} + +// WithSigV4SigningName applies an override to the authentication workflow to +// use the given signing name for SigV4-authenticated operations. +// +// This is an advanced setting. The value here is FINAL, taking precedence over +// the resolved signing name from both auth scheme resolution and endpoint +// resolution. +func WithSigV4SigningName(name string) func(*Options) { + fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, + ) { + return next.HandleInitialize(awsmiddleware.SetSigningName(ctx, name), in) + } + return func(o *Options) { + o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error { + return s.Initialize.Add( + middleware.InitializeMiddlewareFunc("withSigV4SigningName", fn), + middleware.Before, + ) + }) + } +} + +// WithSigV4SigningRegion applies an override to the authentication workflow to +// use the given signing region for SigV4-authenticated operations. +// +// This is an advanced setting. The value here is FINAL, taking precedence over +// the resolved signing region from both auth scheme resolution and endpoint +// resolution. +func WithSigV4SigningRegion(region string) func(*Options) { + fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, + ) { + return next.HandleInitialize(awsmiddleware.SetSigningRegion(ctx, region), in) + } + return func(o *Options) { + o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error { + return s.Initialize.Add( + middleware.InitializeMiddlewareFunc("withSigV4SigningRegion", fn), + middleware.Before, + ) + }) + } +} + +func ignoreAnonymousAuth(options *Options) { + if aws.IsCredentialsProvider(options.Credentials, (*aws.AnonymousCredentials)(nil)) { + options.Credentials = nil + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/serializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/serializers.go index e513d0312fd..fbeb274d4e0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/serializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/serializers.go @@ -2215,6 +2215,61 @@ func (m *awsAwsjson11_serializeOpUntagResource) HandleSerialize(ctx context.Cont return next.HandleSerialize(ctx, in) } +type awsAwsjson11_serializeOpUpdatePullThroughCacheRule struct { +} + +func (*awsAwsjson11_serializeOpUpdatePullThroughCacheRule) ID() string { + return "OperationSerializer" +} + +func (m *awsAwsjson11_serializeOpUpdatePullThroughCacheRule) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + request, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} + } + + input, ok := in.Parameters.(*UpdatePullThroughCacheRuleInput) + _ = input + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} + } + + operationPath := "/" + if len(request.Request.URL.Path) == 0 { + request.Request.URL.Path = operationPath + } else { + request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) + if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { + request.Request.URL.Path += "/" + } + } + request.Request.Method = "POST" + httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") + httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonEC2ContainerRegistry_V20150921.UpdatePullThroughCacheRule") + + jsonEncoder := smithyjson.NewEncoder() + if err := awsAwsjson11_serializeOpDocumentUpdatePullThroughCacheRuleInput(input, jsonEncoder.Value); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + in.Request = request + + return next.HandleSerialize(ctx, in) +} + type awsAwsjson11_serializeOpUploadLayerPart struct { } @@ -2269,6 +2324,61 @@ func (m *awsAwsjson11_serializeOpUploadLayerPart) HandleSerialize(ctx context.Co return next.HandleSerialize(ctx, in) } + +type awsAwsjson11_serializeOpValidatePullThroughCacheRule struct { +} + +func (*awsAwsjson11_serializeOpValidatePullThroughCacheRule) ID() string { + return "OperationSerializer" +} + +func (m *awsAwsjson11_serializeOpValidatePullThroughCacheRule) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + request, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown transport type %T", in.Request)} + } + + input, ok := in.Parameters.(*ValidatePullThroughCacheRuleInput) + _ = input + if !ok { + return out, metadata, &smithy.SerializationError{Err: fmt.Errorf("unknown input parameters type %T", in.Parameters)} + } + + operationPath := "/" + if len(request.Request.URL.Path) == 0 { + request.Request.URL.Path = operationPath + } else { + request.Request.URL.Path = path.Join(request.Request.URL.Path, operationPath) + if request.Request.URL.Path != "/" && operationPath[len(operationPath)-1] == '/' { + request.Request.URL.Path += "/" + } + } + request.Request.Method = "POST" + httpBindingEncoder, err := httpbinding.NewEncoder(request.URL.Path, request.URL.RawQuery, request.Header) + if err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + httpBindingEncoder.SetHeader("Content-Type").String("application/x-amz-json-1.1") + httpBindingEncoder.SetHeader("X-Amz-Target").String("AmazonEC2ContainerRegistry_V20150921.ValidatePullThroughCacheRule") + + jsonEncoder := smithyjson.NewEncoder() + if err := awsAwsjson11_serializeOpDocumentValidatePullThroughCacheRuleInput(input, jsonEncoder.Value); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request, err = request.SetStream(bytes.NewReader(jsonEncoder.Bytes())); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + + if request.Request, err = httpBindingEncoder.Encode(request.Request); err != nil { + return out, metadata, &smithy.SerializationError{Err: err} + } + in.Request = request + + return next.HandleSerialize(ctx, in) +} func awsAwsjson11_serializeDocumentBatchedOperationLayerDigestList(v []string, value smithyjson.Value) error { array := value.Array() defer array.Close() @@ -2778,6 +2888,11 @@ func awsAwsjson11_serializeOpDocumentCreatePullThroughCacheRuleInput(v *CreatePu object := value.Object() defer object.Close() + if v.CredentialArn != nil { + ok := object.Key("credentialArn") + ok.String(*v.CredentialArn) + } + if v.EcrRepositoryPrefix != nil { ok := object.Key("ecrRepositoryPrefix") ok.String(*v.EcrRepositoryPrefix) @@ -2788,6 +2903,11 @@ func awsAwsjson11_serializeOpDocumentCreatePullThroughCacheRuleInput(v *CreatePu ok.String(*v.RegistryId) } + if len(v.UpstreamRegistry) > 0 { + ok := object.Key("upstreamRegistry") + ok.String(string(v.UpstreamRegistry)) + } + if v.UpstreamRegistryUrl != nil { ok := object.Key("upstreamRegistryUrl") ok.String(*v.UpstreamRegistryUrl) @@ -3532,6 +3652,28 @@ func awsAwsjson11_serializeOpDocumentUntagResourceInput(v *UntagResourceInput, v return nil } +func awsAwsjson11_serializeOpDocumentUpdatePullThroughCacheRuleInput(v *UpdatePullThroughCacheRuleInput, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.CredentialArn != nil { + ok := object.Key("credentialArn") + ok.String(*v.CredentialArn) + } + + if v.EcrRepositoryPrefix != nil { + ok := object.Key("ecrRepositoryPrefix") + ok.String(*v.EcrRepositoryPrefix) + } + + if v.RegistryId != nil { + ok := object.Key("registryId") + ok.String(*v.RegistryId) + } + + return nil +} + func awsAwsjson11_serializeOpDocumentUploadLayerPartInput(v *UploadLayerPartInput, value smithyjson.Value) error { object := value.Object() defer object.Close() @@ -3568,3 +3710,20 @@ func awsAwsjson11_serializeOpDocumentUploadLayerPartInput(v *UploadLayerPartInpu return nil } + +func awsAwsjson11_serializeOpDocumentValidatePullThroughCacheRuleInput(v *ValidatePullThroughCacheRuleInput, value smithyjson.Value) error { + object := value.Object() + defer object.Close() + + if v.EcrRepositoryPrefix != nil { + ok := object.Key("ecrRepositoryPrefix") + ok.String(*v.EcrRepositoryPrefix) + } + + if v.RegistryId != nil { + ok := object.Key("registryId") + ok.String(*v.RegistryId) + } + + return nil +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go index d782c4ec9c2..1ff5684677f 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/enums.go @@ -73,6 +73,9 @@ const ( ImageFailureCodeMissingDigestAndTag ImageFailureCode = "MissingDigestAndTag" ImageFailureCodeImageReferencedByManifestList ImageFailureCode = "ImageReferencedByManifestList" ImageFailureCodeKmsError ImageFailureCode = "KmsError" + ImageFailureCodeUpstreamAccessDenied ImageFailureCode = "UpstreamAccessDenied" + ImageFailureCodeUpstreamTooManyRequests ImageFailureCode = "UpstreamTooManyRequests" + ImageFailureCodeUpstreamUnavailable ImageFailureCode = "UpstreamUnavailable" ) // Values returns all known values for ImageFailureCode. Note that this can be @@ -87,6 +90,9 @@ func (ImageFailureCode) Values() []ImageFailureCode { "MissingDigestAndTag", "ImageReferencedByManifestList", "KmsError", + "UpstreamAccessDenied", + "UpstreamTooManyRequests", + "UpstreamUnavailable", } } @@ -324,3 +330,29 @@ func (TagStatus) Values() []TagStatus { "ANY", } } + +type UpstreamRegistry string + +// Enum values for UpstreamRegistry +const ( + UpstreamRegistryEcrPublic UpstreamRegistry = "ecr-public" + UpstreamRegistryQuay UpstreamRegistry = "quay" + UpstreamRegistryK8s UpstreamRegistry = "k8s" + UpstreamRegistryDockerHub UpstreamRegistry = "docker-hub" + UpstreamRegistryGitHubContainerRegistry UpstreamRegistry = "github-container-registry" + UpstreamRegistryAzureContainerRegistry UpstreamRegistry = "azure-container-registry" +) + +// Values returns all known values for UpstreamRegistry. Note that this can be +// expanded in the future, and so it is only as up to date as the client. The +// ordering of this slice is not guaranteed to be stable across updates. +func (UpstreamRegistry) Values() []UpstreamRegistry { + return []UpstreamRegistry{ + "ecr-public", + "quay", + "k8s", + "docker-hub", + "github-container-registry", + "azure-container-registry", + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/errors.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/errors.go index 4b4782c5a5d..01365bf0bf9 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/errors.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/errors.go @@ -744,6 +744,33 @@ func (e *ScanNotFoundException) ErrorCode() string { } func (e *ScanNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } +// The ARN of the secret specified in the pull through cache rule was not found. +// Update the pull through cache rule with a valid secret ARN and try again. +type SecretNotFoundException struct { + Message *string + + ErrorCodeOverride *string + + noSmithyDocumentSerde +} + +func (e *SecretNotFoundException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *SecretNotFoundException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *SecretNotFoundException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "SecretNotFoundException" + } + return *e.ErrorCodeOverride +} +func (e *SecretNotFoundException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } + // These errors are usually caused by a server-side issue. type ServerException struct { Message *string @@ -797,6 +824,117 @@ func (e *TooManyTagsException) ErrorCode() string { } func (e *TooManyTagsException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } +// The secret is unable to be accessed. Verify the resource permissions for the +// secret and try again. +type UnableToAccessSecretException struct { + Message *string + + ErrorCodeOverride *string + + noSmithyDocumentSerde +} + +func (e *UnableToAccessSecretException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *UnableToAccessSecretException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *UnableToAccessSecretException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "UnableToAccessSecretException" + } + return *e.ErrorCodeOverride +} +func (e *UnableToAccessSecretException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } + +// The secret is accessible but is unable to be decrypted. Verify the resource +// permisisons and try again. +type UnableToDecryptSecretValueException struct { + Message *string + + ErrorCodeOverride *string + + noSmithyDocumentSerde +} + +func (e *UnableToDecryptSecretValueException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *UnableToDecryptSecretValueException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *UnableToDecryptSecretValueException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "UnableToDecryptSecretValueException" + } + return *e.ErrorCodeOverride +} +func (e *UnableToDecryptSecretValueException) ErrorFault() smithy.ErrorFault { + return smithy.FaultClient +} + +// The image or images were unable to be pulled using the pull through cache rule. +// This is usually caused because of an issue with the Secrets Manager secret +// containing the credentials for the upstream registry. +type UnableToGetUpstreamImageException struct { + Message *string + + ErrorCodeOverride *string + + noSmithyDocumentSerde +} + +func (e *UnableToGetUpstreamImageException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *UnableToGetUpstreamImageException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *UnableToGetUpstreamImageException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "UnableToGetUpstreamImageException" + } + return *e.ErrorCodeOverride +} +func (e *UnableToGetUpstreamImageException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } + +// There was an issue getting the upstream layer matching the pull through cache +// rule. +type UnableToGetUpstreamLayerException struct { + Message *string + + ErrorCodeOverride *string + + noSmithyDocumentSerde +} + +func (e *UnableToGetUpstreamLayerException) Error() string { + return fmt.Sprintf("%s: %s", e.ErrorCode(), e.ErrorMessage()) +} +func (e *UnableToGetUpstreamLayerException) ErrorMessage() string { + if e.Message == nil { + return "" + } + return *e.Message +} +func (e *UnableToGetUpstreamLayerException) ErrorCode() string { + if e == nil || e.ErrorCodeOverride == nil { + return "UnableToGetUpstreamLayerException" + } + return *e.ErrorCodeOverride +} +func (e *UnableToGetUpstreamLayerException) ErrorFault() smithy.ErrorFault { return smithy.FaultClient } + // The image is of a type that cannot be scanned. type UnsupportedImageTypeException struct { Message *string diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go index 42509094007..e707591dfa9 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/types/types.go @@ -563,6 +563,10 @@ type PullThroughCacheRule struct { // The date and time the pull through cache was created. CreatedAt *time.Time + // The ARN of the Secrets Manager secret associated with the pull through cache + // rule. + CredentialArn *string + // The Amazon ECR repository prefix associated with the pull through cache rule. EcrRepositoryPrefix *string @@ -570,6 +574,14 @@ type PullThroughCacheRule struct { // through cache rule is associated with. RegistryId *string + // The date and time, in JavaScript date format, when the pull through cache rule + // was last updated. + UpdatedAt *time.Time + + // The name of the upstream source registry associated with the pull through cache + // rule. + UpstreamRegistry UpstreamRegistry + // The upstream registry URL associated with the pull through cache rule. UpstreamRegistryUrl *string @@ -612,7 +624,8 @@ type RegistryScanningRule struct { // The frequency that scans are performed at for a private registry. When the // ENHANCED scan type is specified, the supported scan frequencies are // CONTINUOUS_SCAN and SCAN_ON_PUSH . When the BASIC scan type is specified, the - // SCAN_ON_PUSH and MANUAL scan frequencies are supported. + // SCAN_ON_PUSH scan frequency is supported. If scan on push is not specified, then + // the MANUAL scan frequency is set by default. // // This member is required. ScanFrequency ScanFrequency @@ -700,7 +713,8 @@ type Repository struct { // The Amazon Resource Name (ARN) that identifies the repository. The ARN contains // the arn:aws:ecr namespace, followed by the region of the repository, Amazon Web // Services account ID of the repository owner, repository namespace, and - // repository name. For example, arn:aws:ecr:region:012345678910:repository/test . + // repository name. For example, + // arn:aws:ecr:region:012345678910:repository-namespace/repository-name . RepositoryArn *string // The name of the repository. @@ -715,8 +729,8 @@ type Repository struct { // The filter settings used with image replication. Specifying a repository filter // to a replication rule provides a method for controlling which repositories in a -// private registry are replicated. If no repository filter is specified, all -// images in the repository are replicated. +// private registry are replicated. If no filters are added, the contents of all +// repositories are replicated. type RepositoryFilter struct { // The repository filter details. When the PREFIX_MATCH filter type is specified, @@ -835,9 +849,13 @@ type Tag struct { // One part of a key-value pair that make up a tag. A key is a general label that // acts like a category for more specific tag values. + // + // This member is required. Key *string // A value acts as a descriptor within a tag category (key). + // + // This member is required. Value *string noSmithyDocumentSerde diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/validators.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/validators.go index 9baf8c8cffe..d9889a1148b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/validators.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecr/validators.go @@ -670,6 +670,26 @@ func (m *validateOpUntagResource) HandleInitialize(ctx context.Context, in middl return next.HandleInitialize(ctx, in) } +type validateOpUpdatePullThroughCacheRule struct { +} + +func (*validateOpUpdatePullThroughCacheRule) ID() string { + return "OperationInputValidation" +} + +func (m *validateOpUpdatePullThroughCacheRule) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, +) { + input, ok := in.Parameters.(*UpdatePullThroughCacheRuleInput) + if !ok { + return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) + } + if err := validateOpUpdatePullThroughCacheRuleInput(input); err != nil { + return out, metadata, err + } + return next.HandleInitialize(ctx, in) +} + type validateOpUploadLayerPart struct { } @@ -690,6 +710,26 @@ func (m *validateOpUploadLayerPart) HandleInitialize(ctx context.Context, in mid return next.HandleInitialize(ctx, in) } +type validateOpValidatePullThroughCacheRule struct { +} + +func (*validateOpValidatePullThroughCacheRule) ID() string { + return "OperationInputValidation" +} + +func (m *validateOpValidatePullThroughCacheRule) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, +) { + input, ok := in.Parameters.(*ValidatePullThroughCacheRuleInput) + if !ok { + return out, metadata, fmt.Errorf("unknown input parameters type %T", in.Parameters) + } + if err := validateOpValidatePullThroughCacheRuleInput(input); err != nil { + return out, metadata, err + } + return next.HandleInitialize(ctx, in) +} + func addOpBatchCheckLayerAvailabilityValidationMiddleware(stack *middleware.Stack) error { return stack.Initialize.Add(&validateOpBatchCheckLayerAvailability{}, middleware.After) } @@ -822,10 +862,18 @@ func addOpUntagResourceValidationMiddleware(stack *middleware.Stack) error { return stack.Initialize.Add(&validateOpUntagResource{}, middleware.After) } +func addOpUpdatePullThroughCacheRuleValidationMiddleware(stack *middleware.Stack) error { + return stack.Initialize.Add(&validateOpUpdatePullThroughCacheRule{}, middleware.After) +} + func addOpUploadLayerPartValidationMiddleware(stack *middleware.Stack) error { return stack.Initialize.Add(&validateOpUploadLayerPart{}, middleware.After) } +func addOpValidatePullThroughCacheRuleValidationMiddleware(stack *middleware.Stack) error { + return stack.Initialize.Add(&validateOpValidatePullThroughCacheRule{}, middleware.After) +} + func validateEncryptionConfiguration(v *types.EncryptionConfiguration) error { if v == nil { return nil @@ -1045,6 +1093,41 @@ func validateScanningRepositoryFilterList(v []types.ScanningRepositoryFilter) er } } +func validateTag(v *types.Tag) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "Tag"} + if v.Key == nil { + invalidParams.Add(smithy.NewErrParamRequired("Key")) + } + if v.Value == nil { + invalidParams.Add(smithy.NewErrParamRequired("Value")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + +func validateTagList(v []types.Tag) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "TagList"} + for i := range v { + if err := validateTag(&v[i]); err != nil { + invalidParams.AddNested(fmt.Sprintf("[%d]", i), err.(smithy.InvalidParamsError)) + } + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + func validateOpBatchCheckLayerAvailabilityInput(v *BatchCheckLayerAvailabilityInput) error { if v == nil { return nil @@ -1161,6 +1244,11 @@ func validateOpCreateRepositoryInput(v *CreateRepositoryInput) error { if v.RepositoryName == nil { invalidParams.Add(smithy.NewErrParamRequired("RepositoryName")) } + if v.Tags != nil { + if err := validateTagList(v.Tags); err != nil { + invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) + } + } if v.EncryptionConfiguration != nil { if err := validateEncryptionConfiguration(v.EncryptionConfiguration); err != nil { invalidParams.AddNested("EncryptionConfiguration", err.(smithy.InvalidParamsError)) @@ -1576,6 +1664,10 @@ func validateOpTagResourceInput(v *TagResourceInput) error { } if v.Tags == nil { invalidParams.Add(smithy.NewErrParamRequired("Tags")) + } else if v.Tags != nil { + if err := validateTagList(v.Tags); err != nil { + invalidParams.AddNested("Tags", err.(smithy.InvalidParamsError)) + } } if invalidParams.Len() > 0 { return invalidParams @@ -1602,6 +1694,24 @@ func validateOpUntagResourceInput(v *UntagResourceInput) error { } } +func validateOpUpdatePullThroughCacheRuleInput(v *UpdatePullThroughCacheRuleInput) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "UpdatePullThroughCacheRuleInput"} + if v.EcrRepositoryPrefix == nil { + invalidParams.Add(smithy.NewErrParamRequired("EcrRepositoryPrefix")) + } + if v.CredentialArn == nil { + invalidParams.Add(smithy.NewErrParamRequired("CredentialArn")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} + func validateOpUploadLayerPartInput(v *UploadLayerPartInput) error { if v == nil { return nil @@ -1628,3 +1738,18 @@ func validateOpUploadLayerPartInput(v *UploadLayerPartInput) error { return nil } } + +func validateOpValidatePullThroughCacheRuleInput(v *ValidatePullThroughCacheRuleInput) error { + if v == nil { + return nil + } + invalidParams := smithy.InvalidParamsError{Context: "ValidatePullThroughCacheRuleInput"} + if v.EcrRepositoryPrefix == nil { + invalidParams.Add(smithy.NewErrParamRequired("EcrRepositoryPrefix")) + } + if invalidParams.Len() > 0 { + return invalidParams + } else { + return nil + } +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/CHANGELOG.md b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/CHANGELOG.md index fb5b96f9014..8abb8388d49 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/CHANGELOG.md +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/CHANGELOG.md @@ -1,3 +1,153 @@ +# v1.23.3 (2024-03-18) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.23.2 (2024-03-07) + +* **Bug Fix**: Remove dependency on go-cmp. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.23.1 (2024-02-23) + +* **Bug Fix**: Move all common, SDK-side middleware stack ops into the service client module to prevent cross-module compatibility issues in the future. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.23.0 (2024-02-22) + +* **Feature**: Add middleware stack snapshot tests. + +# v1.22.3 (2024-02-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.22.2 (2024-02-20) + +* **Bug Fix**: When sourcing values for a service's `EndpointParameters`, the lack of a configured region (i.e. `options.Region == ""`) will now translate to a `nil` value for `EndpointParameters.Region` instead of a pointer to the empty string `""`. This will result in a much more explicit error when calling an operation instead of an obscure hostname lookup failure. + +# v1.22.1 (2024-02-15) + +* **Bug Fix**: Correct failure to determine the error type in awsJson services that could occur when errors were modeled with a non-string `code` field. + +# v1.22.0 (2024-02-13) + +* **Feature**: Bump minimum Go version to 1.20 per our language support policy. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.21.6 (2024-01-04) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.21.5 (2023-12-08) + +* **Bug Fix**: Reinstate presence of default Retryer in functional options, but still respect max attempts set therein. + +# v1.21.4 (2023-12-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.21.3 (2023-12-06) + +* **Bug Fix**: Restore pre-refactor auth behavior where all operations could technically be performed anonymously. + +# v1.21.2 (2023-12-01) + +* **Bug Fix**: Correct wrapping of errors in authentication workflow. +* **Bug Fix**: Correctly recognize cache-wrapped instances of AnonymousCredentials at client construction. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.21.1 (2023-11-30) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.21.0 (2023-11-29) + +* **Feature**: Expose Options() accessor on service clients. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.20.5 (2023-11-28.2) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.20.4 (2023-11-28) + +* **Bug Fix**: Respect setting RetryMaxAttempts in functional options at client construction. + +# v1.20.3 (2023-11-20) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.20.2 (2023-11-15) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.20.1 (2023-11-09) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.20.0 (2023-11-01) + +* **Feature**: Adds support for configured endpoints via environment variables and the AWS shared configuration file. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.19.0 (2023-10-31) + +* **Feature**: **BREAKING CHANGE**: Bump minimum go version to 1.19 per the revised [go version support policy](https://aws.amazon.com/blogs/developer/aws-sdk-for-go-aligns-with-go-release-policy-on-supported-runtimes/). +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.2 (2023-10-12) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.1 (2023-10-06) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.18.0 (2023-09-18) + +* **Announcement**: [BREAKFIX] Change in MaxResults datatype from value to pointer type in cognito-sync service. +* **Feature**: Adds several endpoint ruleset changes across all models: smaller rulesets, removed non-unique regional endpoints, fixes FIPS and DualStack endpoints, and make region not required in SDK::Endpoint. Additional breakfix to cognito-sync field. + +# v1.17.5 (2023-08-21) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.17.4 (2023-08-18) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.17.3 (2023-08-17) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.17.2 (2023-08-07) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.17.1 (2023-08-01) + +* No change notes available for this release. + +# v1.17.0 (2023-07-31) + +* **Feature**: Adds support for smithy-modeled endpoint resolution. A new rules-based endpoint resolution will be added to the SDK which will supercede and deprecate existing endpoint resolution. Specifically, EndpointResolver will be deprecated while BaseEndpoint and EndpointResolverV2 will take its place. For more information, please see the Endpoints section in our Developer Guide. +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.16.6 (2023-07-28) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.16.5 (2023-07-13) + +* **Dependency Update**: Updated to the latest SDK module versions + +# v1.16.4 (2023-06-15) + +* No change notes available for this release. + +# v1.16.3 (2023-06-13) + +* **Dependency Update**: Updated to the latest SDK module versions + # v1.16.2 (2023-05-04) * No change notes available for this release. diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_client.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_client.go index f6d77354334..b3758ccf435 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_client.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_client.go @@ -4,12 +4,15 @@ package ecrpublic import ( "context" + "fmt" "github.com/aws/aws-sdk-go-v2/aws" "github.com/aws/aws-sdk-go-v2/aws/defaults" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" "github.com/aws/aws-sdk-go-v2/aws/retry" "github.com/aws/aws-sdk-go-v2/aws/signer/v4" awshttp "github.com/aws/aws-sdk-go-v2/aws/transport/http" + internalauth "github.com/aws/aws-sdk-go-v2/internal/auth" + internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" smithy "github.com/aws/smithy-go" smithydocument "github.com/aws/smithy-go/document" @@ -46,128 +49,48 @@ func New(options Options, optFns ...func(*Options)) *Client { resolveHTTPSignerV4(&options) - resolveDefaultEndpointConfiguration(&options) + resolveEndpointResolverV2(&options) + + resolveAuthSchemeResolver(&options) for _, fn := range optFns { fn(&options) } - client := &Client{ - options: options, - } - - return client -} - -type Options struct { - // Set of options to modify how an operation is invoked. These apply to all - // operations invoked for this client. Use functional options on operation call to - // modify this list for per operation behavior. - APIOptions []func(*middleware.Stack) error - - // Configures the events that will be sent to the configured logger. - ClientLogMode aws.ClientLogMode - - // The credentials object to use when signing requests. - Credentials aws.CredentialsProvider - - // The configuration DefaultsMode that the SDK should use when constructing the - // clients initial default settings. - DefaultsMode aws.DefaultsMode - - // The endpoint options to be used when attempting to resolve an endpoint. - EndpointOptions EndpointResolverOptions - - // The service endpoint resolver. - EndpointResolver EndpointResolver - - // Signature Version 4 (SigV4) Signer - HTTPSignerV4 HTTPSignerV4 - - // The logger writer interface to write logging messages to. - Logger logging.Logger + finalizeRetryMaxAttempts(&options) - // The region to send requests to. (Required) - Region string + ignoreAnonymousAuth(&options) - // RetryMaxAttempts specifies the maximum number attempts an API client will call - // an operation that fails with a retryable error. A value of 0 is ignored, and - // will not be used to configure the API client created default retryer, or modify - // per operation call's retry max attempts. When creating a new API Clients this - // member will only be used if the Retryer Options member is nil. This value will - // be ignored if Retryer is not nil. If specified in an operation call's functional - // options with a value that is different than the constructed client's Options, - // the Client's Retryer will be wrapped to use the operation's specific - // RetryMaxAttempts value. - RetryMaxAttempts int + wrapWithAnonymousAuth(&options) - // RetryMode specifies the retry mode the API client will be created with, if - // Retryer option is not also specified. When creating a new API Clients this - // member will only be used if the Retryer Options member is nil. This value will - // be ignored if Retryer is not nil. Currently does not support per operation call - // overrides, may in the future. - RetryMode aws.RetryMode + resolveAuthSchemes(&options) - // Retryer guides how HTTP requests should be retried in case of recoverable - // failures. When nil the API client will use a default retryer. The kind of - // default retry created by the API client can be changed with the RetryMode - // option. - Retryer aws.Retryer - - // The RuntimeEnvironment configuration, only populated if the DefaultsMode is set - // to DefaultsModeAuto and is initialized using config.LoadDefaultConfig . You - // should not populate this structure programmatically, or rely on the values here - // within your applications. - RuntimeEnvironment aws.RuntimeEnvironment - - // The initial DefaultsMode used when the client options were constructed. If the - // DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved - // value was at that point in time. Currently does not support per operation call - // overrides, may in the future. - resolvedDefaultsMode aws.DefaultsMode - - // The HTTP client to invoke API calls with. Defaults to client's default HTTP - // implementation if nil. - HTTPClient HTTPClient -} - -// WithAPIOptions returns a functional option for setting the Client's APIOptions -// option. -func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { - return func(o *Options) { - o.APIOptions = append(o.APIOptions, optFns...) + client := &Client{ + options: options, } -} -// WithEndpointResolver returns a functional option for setting the Client's -// EndpointResolver option. -func WithEndpointResolver(v EndpointResolver) func(*Options) { - return func(o *Options) { - o.EndpointResolver = v - } + return client } -type HTTPClient interface { - Do(*http.Request) (*http.Response, error) +// Options returns a copy of the client configuration. +// +// Callers SHOULD NOT perform mutations on any inner structures within client +// config. Config overrides should instead be made on a per-operation basis through +// functional options. +func (c *Client) Options() Options { + return c.options.Copy() } -// Copy creates a clone where the APIOptions list is deep copied. -func (o Options) Copy() Options { - to := o - to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) - copy(to.APIOptions, o.APIOptions) - - return to -} func (c *Client) invokeOperation(ctx context.Context, opID string, params interface{}, optFns []func(*Options), stackFns ...func(*middleware.Stack, Options) error) (result interface{}, metadata middleware.Metadata, err error) { ctx = middleware.ClearStackValues(ctx) stack := middleware.NewStack(opID, smithyhttp.NewStackRequest) options := c.options.Copy() + for _, fn := range optFns { fn(&options) } - finalizeRetryMaxAttemptOptions(&options, *c) + finalizeOperationRetryMaxAttempts(&options, *c) finalizeClientEndpointResolverOptions(&options) @@ -195,8 +118,89 @@ func (c *Client) invokeOperation(ctx context.Context, opID string, params interf return result, metadata, err } +type operationInputKey struct{} + +func setOperationInput(ctx context.Context, input interface{}) context.Context { + return middleware.WithStackValue(ctx, operationInputKey{}, input) +} + +func getOperationInput(ctx context.Context) interface{} { + return middleware.GetStackValue(ctx, operationInputKey{}) +} + +type setOperationInputMiddleware struct { +} + +func (*setOperationInputMiddleware) ID() string { + return "setOperationInput" +} + +func (m *setOperationInputMiddleware) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( + out middleware.SerializeOutput, metadata middleware.Metadata, err error, +) { + ctx = setOperationInput(ctx, in.Parameters) + return next.HandleSerialize(ctx, in) +} + +func addProtocolFinalizerMiddlewares(stack *middleware.Stack, options Options, operation string) error { + if err := stack.Finalize.Add(&resolveAuthSchemeMiddleware{operation: operation, options: options}, middleware.Before); err != nil { + return fmt.Errorf("add ResolveAuthScheme: %w", err) + } + if err := stack.Finalize.Insert(&getIdentityMiddleware{options: options}, "ResolveAuthScheme", middleware.After); err != nil { + return fmt.Errorf("add GetIdentity: %v", err) + } + if err := stack.Finalize.Insert(&resolveEndpointV2Middleware{options: options}, "GetIdentity", middleware.After); err != nil { + return fmt.Errorf("add ResolveEndpointV2: %v", err) + } + if err := stack.Finalize.Insert(&signRequestMiddleware{}, "ResolveEndpointV2", middleware.After); err != nil { + return fmt.Errorf("add Signing: %w", err) + } + return nil +} +func resolveAuthSchemeResolver(options *Options) { + if options.AuthSchemeResolver == nil { + options.AuthSchemeResolver = &defaultAuthSchemeResolver{} + } +} + +func resolveAuthSchemes(options *Options) { + if options.AuthSchemes == nil { + options.AuthSchemes = []smithyhttp.AuthScheme{ + internalauth.NewHTTPAuthScheme("aws.auth#sigv4", &internalauthsmithy.V4SignerAdapter{ + Signer: options.HTTPSignerV4, + Logger: options.Logger, + LogSigning: options.ClientLogMode.IsSigning(), + }), + } + } +} + type noSmithyDocumentSerde = smithydocument.NoSerde +type legacyEndpointContextSetter struct { + LegacyResolver EndpointResolver +} + +func (*legacyEndpointContextSetter) ID() string { + return "legacyEndpointContextSetter" +} + +func (m *legacyEndpointContextSetter) HandleInitialize(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, +) { + if m.LegacyResolver != nil { + ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, true) + } + + return next.HandleInitialize(ctx, in) + +} +func addlegacyEndpointContextSetter(stack *middleware.Stack, o Options) error { + return stack.Initialize.Add(&legacyEndpointContextSetter{ + LegacyResolver: o.EndpointResolver, + }, middleware.Before) +} + func resolveDefaultLogger(o *Options) { if o.Logger != nil { return @@ -234,6 +238,7 @@ func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { APIOptions: cfg.APIOptions, Logger: cfg.Logger, ClientLogMode: cfg.ClientLogMode, + AppID: cfg.AppID, } resolveAWSRetryerProvider(cfg, &opts) resolveAWSRetryMaxAttempts(cfg, &opts) @@ -241,6 +246,7 @@ func NewFromConfig(cfg aws.Config, optFns ...func(*Options)) *Client { resolveAWSEndpointResolver(cfg, &opts) resolveUseDualStackEndpoint(cfg, &opts) resolveUseFIPSEndpoint(cfg, &opts) + resolveBaseEndpoint(cfg, &opts) return New(opts, optFns...) } @@ -332,7 +338,15 @@ func resolveAWSRetryMaxAttempts(cfg aws.Config, o *Options) { o.RetryMaxAttempts = cfg.RetryMaxAttempts } -func finalizeRetryMaxAttemptOptions(o *Options, client Client) { +func finalizeRetryMaxAttempts(o *Options) { + if o.RetryMaxAttempts == 0 { + return + } + + o.Retryer = retry.AddWithMaxAttempts(o.Retryer, o.RetryMaxAttempts) +} + +func finalizeOperationRetryMaxAttempts(o *Options, client Client) { if v := o.RetryMaxAttempts; v == 0 || v == client.options.RetryMaxAttempts { return } @@ -344,20 +358,39 @@ func resolveAWSEndpointResolver(cfg aws.Config, o *Options) { if cfg.EndpointResolver == nil && cfg.EndpointResolverWithOptions == nil { return } - o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions, NewDefaultEndpointResolver()) + o.EndpointResolver = withEndpointResolver(cfg.EndpointResolver, cfg.EndpointResolverWithOptions) } -func addClientUserAgent(stack *middleware.Stack) error { - return awsmiddleware.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "ecrpublic", goModuleVersion)(stack) +func addClientUserAgent(stack *middleware.Stack, options Options) error { + ua, err := getOrAddRequestUserAgent(stack) + if err != nil { + return err + } + + ua.AddSDKAgentKeyValue(awsmiddleware.APIMetadata, "ecrpublic", goModuleVersion) + if len(options.AppID) > 0 { + ua.AddSDKAgentKey(awsmiddleware.ApplicationIdentifier, options.AppID) + } + + return nil } -func addHTTPSignerV4Middleware(stack *middleware.Stack, o Options) error { - mw := v4.NewSignHTTPRequestMiddleware(v4.SignHTTPRequestMiddlewareOptions{ - CredentialsProvider: o.Credentials, - Signer: o.HTTPSignerV4, - LogSigning: o.ClientLogMode.IsSigning(), - }) - return stack.Finalize.Add(mw, middleware.After) +func getOrAddRequestUserAgent(stack *middleware.Stack) (*awsmiddleware.RequestUserAgent, error) { + id := (*awsmiddleware.RequestUserAgent)(nil).ID() + mw, ok := stack.Build.Get(id) + if !ok { + mw = awsmiddleware.NewRequestUserAgent() + if err := stack.Build.Add(mw, middleware.After); err != nil { + return nil, err + } + } + + ua, ok := mw.(*awsmiddleware.RequestUserAgent) + if !ok { + return nil, fmt.Errorf("%T for %s middleware did not match expected type", mw, id) + } + + return ua, nil } type HTTPSignerV4 interface { @@ -378,12 +411,48 @@ func newDefaultV4Signer(o Options) *v4.Signer { }) } -func addRetryMiddlewares(stack *middleware.Stack, o Options) error { - mo := retry.AddRetryMiddlewaresOptions{ - Retryer: o.Retryer, - LogRetryAttempts: o.ClientLogMode.IsRetries(), +func addClientRequestID(stack *middleware.Stack) error { + return stack.Build.Add(&awsmiddleware.ClientRequestID{}, middleware.After) +} + +func addComputeContentLength(stack *middleware.Stack) error { + return stack.Build.Add(&smithyhttp.ComputeContentLength{}, middleware.After) +} + +func addRawResponseToMetadata(stack *middleware.Stack) error { + return stack.Deserialize.Add(&awsmiddleware.AddRawResponse{}, middleware.Before) +} + +func addRecordResponseTiming(stack *middleware.Stack) error { + return stack.Deserialize.Add(&awsmiddleware.RecordResponseTiming{}, middleware.After) +} +func addStreamingEventsPayload(stack *middleware.Stack) error { + return stack.Finalize.Add(&v4.StreamingEventsPayload{}, middleware.Before) +} + +func addUnsignedPayload(stack *middleware.Stack) error { + return stack.Finalize.Insert(&v4.UnsignedPayload{}, "ResolveEndpointV2", middleware.After) +} + +func addComputePayloadSHA256(stack *middleware.Stack) error { + return stack.Finalize.Insert(&v4.ComputePayloadSHA256{}, "ResolveEndpointV2", middleware.After) +} + +func addContentSHA256Header(stack *middleware.Stack) error { + return stack.Finalize.Insert(&v4.ContentSHA256Header{}, (*v4.ComputePayloadSHA256)(nil).ID(), middleware.After) +} + +func addRetry(stack *middleware.Stack, o Options) error { + attempt := retry.NewAttemptMiddleware(o.Retryer, smithyhttp.RequestCloner, func(m *retry.Attempt) { + m.LogAttempts = o.ClientLogMode.IsRetries() + }) + if err := stack.Finalize.Insert(attempt, "Signing", middleware.Before); err != nil { + return err + } + if err := stack.Finalize.Insert(&retry.MetricsHeader{}, attempt.ID(), middleware.After); err != nil { + return err } - return retry.AddRetryMiddlewares(stack, mo) + return nil } // resolves dual-stack endpoint configuration @@ -416,12 +485,18 @@ func resolveUseFIPSEndpoint(cfg aws.Config, o *Options) error { return nil } +func addRecursionDetection(stack *middleware.Stack) error { + return stack.Build.Add(&awsmiddleware.RecursionDetection{}, middleware.After) +} + func addRequestIDRetrieverMiddleware(stack *middleware.Stack) error { - return awsmiddleware.AddRequestIDRetrieverMiddleware(stack) + return stack.Deserialize.Insert(&awsmiddleware.RequestIDRetriever{}, "OperationDeserializer", middleware.Before) + } func addResponseErrorMiddleware(stack *middleware.Stack) error { - return awshttp.AddResponseErrorMiddleware(stack) + return stack.Deserialize.Insert(&awshttp.ResponseErrorWrapper{}, "RequestIDRetriever", middleware.Before) + } func addRequestResponseLogging(stack *middleware.Stack, o Options) error { @@ -432,3 +507,32 @@ func addRequestResponseLogging(stack *middleware.Stack, o Options) error { LogResponseWithBody: o.ClientLogMode.IsResponseWithBody(), }, middleware.After) } + +type disableHTTPSMiddleware struct { + DisableHTTPS bool +} + +func (*disableHTTPSMiddleware) ID() string { + return "disableHTTPS" +} + +func (m *disableHTTPSMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + req, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.DisableHTTPS && !smithyhttp.GetHostnameImmutable(ctx) { + req.URL.Scheme = "http" + } + + return next.HandleFinalize(ctx, in) +} + +func addDisableHTTPSMiddleware(stack *middleware.Stack, o Options) error { + return stack.Finalize.Insert(&disableHTTPSMiddleware{ + DisableHTTPS: o.EndpointOptions.DisableHTTPS, + }, "ResolveEndpointV2", middleware.After) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchCheckLayerAvailability.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchCheckLayerAvailability.go index 0962a06e079..ab4cb1e548e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchCheckLayerAvailability.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchCheckLayerAvailability.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -68,6 +68,9 @@ type BatchCheckLayerAvailabilityOutput struct { } func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpBatchCheckLayerAvailability{}, middleware.After) if err != nil { return err @@ -76,34 +79,38 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "BatchCheckLayerAvailability"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -112,13 +119,16 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpBatchCheckLayerAvailabilityValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opBatchCheckLayerAvailability(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -130,6 +140,9 @@ func (c *Client) addOperationBatchCheckLayerAvailabilityMiddlewares(stack *middl if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -137,7 +150,6 @@ func newServiceMetadataMiddleware_opBatchCheckLayerAvailability(region string) * return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "BatchCheckLayerAvailability", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchDeleteImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchDeleteImage.go index 8ea3aa36536..4ff2a07ef78 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchDeleteImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_BatchDeleteImage.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -68,6 +68,9 @@ type BatchDeleteImageOutput struct { } func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpBatchDeleteImage{}, middleware.After) if err != nil { return err @@ -76,34 +79,38 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "BatchDeleteImage"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -112,13 +119,16 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpBatchDeleteImageValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opBatchDeleteImage(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -130,6 +140,9 @@ func (c *Client) addOperationBatchDeleteImageMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -137,7 +150,6 @@ func newServiceMetadataMiddleware_opBatchDeleteImage(region string) *awsmiddlewa return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "BatchDeleteImage", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CompleteLayerUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CompleteLayerUpload.go index cf1bf511ded..7a95db650f0 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CompleteLayerUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CompleteLayerUpload.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -80,6 +80,9 @@ type CompleteLayerUploadOutput struct { } func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpCompleteLayerUpload{}, middleware.After) if err != nil { return err @@ -88,34 +91,38 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "CompleteLayerUpload"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -124,13 +131,16 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpCompleteLayerUploadValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCompleteLayerUpload(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -142,6 +152,9 @@ func (c *Client) addOperationCompleteLayerUploadMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -149,7 +162,6 @@ func newServiceMetadataMiddleware_opCompleteLayerUpload(region string) *awsmiddl return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "CompleteLayerUpload", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CreateRepository.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CreateRepository.go index 9586b3e3880..812926059a2 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CreateRepository.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_CreateRepository.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -68,6 +68,9 @@ type CreateRepositoryOutput struct { } func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpCreateRepository{}, middleware.After) if err != nil { return err @@ -76,34 +79,38 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "CreateRepository"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -112,13 +119,16 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpCreateRepositoryValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opCreateRepository(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -130,6 +140,9 @@ func (c *Client) addOperationCreateRepositoryMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -137,7 +150,6 @@ func newServiceMetadataMiddleware_opCreateRepository(region string) *awsmiddlewa return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "CreateRepository", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepository.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepository.go index 7fe23d70fac..1392b24526b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepository.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepository.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -61,6 +61,9 @@ type DeleteRepositoryOutput struct { } func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteRepository{}, middleware.After) if err != nil { return err @@ -69,34 +72,38 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteRepository"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -105,13 +112,16 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpDeleteRepositoryValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteRepository(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -123,6 +133,9 @@ func (c *Client) addOperationDeleteRepositoryMiddlewares(stack *middleware.Stack if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -130,7 +143,6 @@ func newServiceMetadataMiddleware_opDeleteRepository(region string) *awsmiddlewa return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "DeleteRepository", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepositoryPolicy.go index 20a8b70d438..fc16deb8a26 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DeleteRepositoryPolicy.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -60,6 +60,9 @@ type DeleteRepositoryPolicyOutput struct { } func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDeleteRepositoryPolicy{}, middleware.After) if err != nil { return err @@ -68,34 +71,38 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DeleteRepositoryPolicy"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -104,13 +111,16 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpDeleteRepositoryPolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDeleteRepositoryPolicy(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -122,6 +132,9 @@ func (c *Client) addOperationDeleteRepositoryPolicyMiddlewares(stack *middleware if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -129,7 +142,6 @@ func newServiceMetadataMiddleware_opDeleteRepositoryPolicy(region string) *awsmi return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "DeleteRepositoryPolicy", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImageTags.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImageTags.go index b13ed17b9e5..fa2e122fe3a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImageTags.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImageTags.go @@ -6,7 +6,6 @@ import ( "context" "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -78,6 +77,9 @@ type DescribeImageTagsOutput struct { } func (c *Client) addOperationDescribeImageTagsMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeImageTags{}, middleware.After) if err != nil { return err @@ -86,34 +88,38 @@ func (c *Client) addOperationDescribeImageTagsMiddlewares(stack *middleware.Stac if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeImageTags"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -122,13 +128,16 @@ func (c *Client) addOperationDescribeImageTagsMiddlewares(stack *middleware.Stac if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpDescribeImageTagsValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeImageTags(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -140,6 +149,9 @@ func (c *Client) addOperationDescribeImageTagsMiddlewares(stack *middleware.Stac if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -244,7 +256,6 @@ func newServiceMetadataMiddleware_opDescribeImageTags(region string) *awsmiddlew return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "DescribeImageTags", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImages.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImages.go index c070863e370..660e640a717 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImages.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeImages.go @@ -6,7 +6,6 @@ import ( "context" "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -85,6 +84,9 @@ type DescribeImagesOutput struct { } func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeImages{}, middleware.After) if err != nil { return err @@ -93,34 +95,38 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeImages"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -129,13 +135,16 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpDescribeImagesValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeImages(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -147,6 +156,9 @@ func (c *Client) addOperationDescribeImagesMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -251,7 +263,6 @@ func newServiceMetadataMiddleware_opDescribeImages(region string) *awsmiddleware return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "DescribeImages", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRegistries.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRegistries.go index 7c3c414416e..a4a0d06c7d8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRegistries.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRegistries.go @@ -6,7 +6,6 @@ import ( "context" "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -72,6 +71,9 @@ type DescribeRegistriesOutput struct { } func (c *Client) addOperationDescribeRegistriesMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeRegistries{}, middleware.After) if err != nil { return err @@ -80,34 +82,38 @@ func (c *Client) addOperationDescribeRegistriesMiddlewares(stack *middleware.Sta if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeRegistries"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -116,10 +122,13 @@ func (c *Client) addOperationDescribeRegistriesMiddlewares(stack *middleware.Sta if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeRegistries(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -131,6 +140,9 @@ func (c *Client) addOperationDescribeRegistriesMiddlewares(stack *middleware.Sta if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -236,7 +248,6 @@ func newServiceMetadataMiddleware_opDescribeRegistries(region string) *awsmiddle return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "DescribeRegistries", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRepositories.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRepositories.go index 1ad26cf7d0b..4646c67603b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRepositories.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_DescribeRepositories.go @@ -6,7 +6,6 @@ import ( "context" "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -81,6 +80,9 @@ type DescribeRepositoriesOutput struct { } func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpDescribeRepositories{}, middleware.After) if err != nil { return err @@ -89,34 +91,38 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "DescribeRepositories"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -125,10 +131,13 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opDescribeRepositories(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -140,6 +149,9 @@ func (c *Client) addOperationDescribeRepositoriesMiddlewares(stack *middleware.S if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -246,7 +258,6 @@ func newServiceMetadataMiddleware_opDescribeRepositories(region string) *awsmidd return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "DescribeRepositories", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetAuthorizationToken.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetAuthorizationToken.go index 0b7eb721799..82d1e20ebfe 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetAuthorizationToken.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetAuthorizationToken.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -47,6 +47,9 @@ type GetAuthorizationTokenOutput struct { } func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetAuthorizationToken{}, middleware.After) if err != nil { return err @@ -55,34 +58,38 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "GetAuthorizationToken"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -91,10 +98,13 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetAuthorizationToken(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -106,6 +116,9 @@ func (c *Client) addOperationGetAuthorizationTokenMiddlewares(stack *middleware. if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -113,7 +126,6 @@ func newServiceMetadataMiddleware_opGetAuthorizationToken(region string) *awsmid return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "GetAuthorizationToken", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRegistryCatalogData.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRegistryCatalogData.go index 4f1b2d42c1f..b6aea611700 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRegistryCatalogData.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRegistryCatalogData.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -45,6 +45,9 @@ type GetRegistryCatalogDataOutput struct { } func (c *Client) addOperationGetRegistryCatalogDataMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetRegistryCatalogData{}, middleware.After) if err != nil { return err @@ -53,34 +56,38 @@ func (c *Client) addOperationGetRegistryCatalogDataMiddlewares(stack *middleware if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "GetRegistryCatalogData"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -89,10 +96,13 @@ func (c *Client) addOperationGetRegistryCatalogDataMiddlewares(stack *middleware if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRegistryCatalogData(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -104,6 +114,9 @@ func (c *Client) addOperationGetRegistryCatalogDataMiddlewares(stack *middleware if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -111,7 +124,6 @@ func newServiceMetadataMiddleware_opGetRegistryCatalogData(region string) *awsmi return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "GetRegistryCatalogData", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryCatalogData.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryCatalogData.go index fd5877a415e..b7fc89975e6 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryCatalogData.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryCatalogData.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -55,6 +55,9 @@ type GetRepositoryCatalogDataOutput struct { } func (c *Client) addOperationGetRepositoryCatalogDataMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetRepositoryCatalogData{}, middleware.After) if err != nil { return err @@ -63,34 +66,38 @@ func (c *Client) addOperationGetRepositoryCatalogDataMiddlewares(stack *middlewa if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "GetRepositoryCatalogData"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -99,13 +106,16 @@ func (c *Client) addOperationGetRepositoryCatalogDataMiddlewares(stack *middlewa if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpGetRepositoryCatalogDataValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRepositoryCatalogData(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -117,6 +127,9 @@ func (c *Client) addOperationGetRepositoryCatalogDataMiddlewares(stack *middlewa if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -124,7 +137,6 @@ func newServiceMetadataMiddleware_opGetRepositoryCatalogData(region string) *aws return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "GetRepositoryCatalogData", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryPolicy.go index 90fc8293432..677f128dacb 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_GetRepositoryPolicy.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -60,6 +60,9 @@ type GetRepositoryPolicyOutput struct { } func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpGetRepositoryPolicy{}, middleware.After) if err != nil { return err @@ -68,34 +71,38 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "GetRepositoryPolicy"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -104,13 +111,16 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpGetRepositoryPolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opGetRepositoryPolicy(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -122,6 +132,9 @@ func (c *Client) addOperationGetRepositoryPolicyMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -129,7 +142,6 @@ func newServiceMetadataMiddleware_opGetRepositoryPolicy(region string) *awsmiddl return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "GetRepositoryPolicy", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_InitiateLayerUpload.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_InitiateLayerUpload.go index 42ca47b3d11..c0d7d0f637e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_InitiateLayerUpload.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_InitiateLayerUpload.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -62,6 +62,9 @@ type InitiateLayerUploadOutput struct { } func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpInitiateLayerUpload{}, middleware.After) if err != nil { return err @@ -70,34 +73,38 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "InitiateLayerUpload"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -106,13 +113,16 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpInitiateLayerUploadValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opInitiateLayerUpload(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -124,6 +134,9 @@ func (c *Client) addOperationInitiateLayerUploadMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -131,7 +144,6 @@ func newServiceMetadataMiddleware_opInitiateLayerUpload(region string) *awsmiddl return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "InitiateLayerUpload", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_ListTagsForResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_ListTagsForResource.go index 0ffad3cc04e..1350ecd3f96 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_ListTagsForResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_ListTagsForResource.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -50,6 +50,9 @@ type ListTagsForResourceOutput struct { } func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpListTagsForResource{}, middleware.After) if err != nil { return err @@ -58,34 +61,38 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "ListTagsForResource"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -94,13 +101,16 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpListTagsForResourceValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opListTagsForResource(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -112,6 +122,9 @@ func (c *Client) addOperationListTagsForResourceMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -119,7 +132,6 @@ func newServiceMetadataMiddleware_opListTagsForResource(region string) *awsmiddl return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "ListTagsForResource", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutImage.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutImage.go index 91d681d544a..55efd6e929b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutImage.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutImage.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -77,6 +77,9 @@ type PutImageOutput struct { } func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutImage{}, middleware.After) if err != nil { return err @@ -85,34 +88,38 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "PutImage"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -121,13 +128,16 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpPutImageValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutImage(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -139,6 +149,9 @@ func (c *Client) addOperationPutImageMiddlewares(stack *middleware.Stack, option if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -146,7 +159,6 @@ func newServiceMetadataMiddleware_opPutImage(region string) *awsmiddleware.Regis return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "PutImage", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRegistryCatalogData.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRegistryCatalogData.go index c6677f81103..f54f633f2e8 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRegistryCatalogData.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRegistryCatalogData.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -51,6 +51,9 @@ type PutRegistryCatalogDataOutput struct { } func (c *Client) addOperationPutRegistryCatalogDataMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutRegistryCatalogData{}, middleware.After) if err != nil { return err @@ -59,34 +62,38 @@ func (c *Client) addOperationPutRegistryCatalogDataMiddlewares(stack *middleware if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "PutRegistryCatalogData"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -95,10 +102,13 @@ func (c *Client) addOperationPutRegistryCatalogDataMiddlewares(stack *middleware if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutRegistryCatalogData(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -110,6 +120,9 @@ func (c *Client) addOperationPutRegistryCatalogDataMiddlewares(stack *middleware if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -117,7 +130,6 @@ func newServiceMetadataMiddleware_opPutRegistryCatalogData(region string) *awsmi return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "PutRegistryCatalogData", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRepositoryCatalogData.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRepositoryCatalogData.go index 70e5d3c3c11..45d1382fb6e 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRepositoryCatalogData.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_PutRepositoryCatalogData.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -60,6 +60,9 @@ type PutRepositoryCatalogDataOutput struct { } func (c *Client) addOperationPutRepositoryCatalogDataMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpPutRepositoryCatalogData{}, middleware.After) if err != nil { return err @@ -68,34 +71,38 @@ func (c *Client) addOperationPutRepositoryCatalogDataMiddlewares(stack *middlewa if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "PutRepositoryCatalogData"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -104,13 +111,16 @@ func (c *Client) addOperationPutRepositoryCatalogDataMiddlewares(stack *middlewa if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpPutRepositoryCatalogDataValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opPutRepositoryCatalogData(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -122,6 +132,9 @@ func (c *Client) addOperationPutRepositoryCatalogDataMiddlewares(stack *middlewa if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -129,7 +142,6 @@ func newServiceMetadataMiddleware_opPutRepositoryCatalogData(region string) *aws return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "PutRepositoryCatalogData", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_SetRepositoryPolicy.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_SetRepositoryPolicy.go index ff5cbd65da7..d3a93d1d514 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_SetRepositoryPolicy.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_SetRepositoryPolicy.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -73,6 +73,9 @@ type SetRepositoryPolicyOutput struct { } func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpSetRepositoryPolicy{}, middleware.After) if err != nil { return err @@ -81,34 +84,38 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "SetRepositoryPolicy"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -117,13 +124,16 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpSetRepositoryPolicyValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opSetRepositoryPolicy(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -135,6 +145,9 @@ func (c *Client) addOperationSetRepositoryPolicyMiddlewares(stack *middleware.St if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -142,7 +155,6 @@ func newServiceMetadataMiddleware_opSetRepositoryPolicy(region string) *awsmiddl return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "SetRepositoryPolicy", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_TagResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_TagResource.go index b4cf870d560..4f68992313a 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_TagResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_TagResource.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/aws-sdk-go-v2/service/ecrpublic/types" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" @@ -56,6 +56,9 @@ type TagResourceOutput struct { } func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpTagResource{}, middleware.After) if err != nil { return err @@ -64,34 +67,38 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "TagResource"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -100,13 +107,16 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpTagResourceValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opTagResource(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -118,6 +128,9 @@ func (c *Client) addOperationTagResourceMiddlewares(stack *middleware.Stack, opt if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -125,7 +138,6 @@ func newServiceMetadataMiddleware_opTagResource(region string) *awsmiddleware.Re return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "TagResource", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UntagResource.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UntagResource.go index 66502ca4acc..8ebfae032ba 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UntagResource.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UntagResource.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -50,6 +50,9 @@ type UntagResourceOutput struct { } func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpUntagResource{}, middleware.After) if err != nil { return err @@ -58,34 +61,38 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "UntagResource"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -94,13 +101,16 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpUntagResourceValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUntagResource(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -112,6 +122,9 @@ func (c *Client) addOperationUntagResourceMiddlewares(stack *middleware.Stack, o if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -119,7 +132,6 @@ func newServiceMetadataMiddleware_opUntagResource(region string) *awsmiddleware. return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "UntagResource", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UploadLayerPart.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UploadLayerPart.go index f194f0c1a1a..bc5d65206fc 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UploadLayerPart.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/api_op_UploadLayerPart.go @@ -4,8 +4,8 @@ package ecrpublic import ( "context" + "fmt" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" - "github.com/aws/aws-sdk-go-v2/aws/signer/v4" "github.com/aws/smithy-go/middleware" smithyhttp "github.com/aws/smithy-go/transport/http" ) @@ -88,6 +88,9 @@ type UploadLayerPartOutput struct { } func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, options Options) (err error) { + if err := stack.Serialize.Add(&setOperationInputMiddleware{}, middleware.After); err != nil { + return err + } err = stack.Serialize.Add(&awsAwsjson11_serializeOpUploadLayerPart{}, middleware.After) if err != nil { return err @@ -96,34 +99,38 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err != nil { return err } - if err = addSetLoggerMiddleware(stack, options); err != nil { + if err := addProtocolFinalizerMiddlewares(stack, options, "UploadLayerPart"); err != nil { + return fmt.Errorf("add protocol finalizers: %v", err) + } + + if err = addlegacyEndpointContextSetter(stack, options); err != nil { return err } - if err = awsmiddleware.AddClientRequestIDMiddleware(stack); err != nil { + if err = addSetLoggerMiddleware(stack, options); err != nil { return err } - if err = smithyhttp.AddComputeContentLengthMiddleware(stack); err != nil { + if err = addClientRequestID(stack); err != nil { return err } - if err = addResolveEndpointMiddleware(stack, options); err != nil { + if err = addComputeContentLength(stack); err != nil { return err } - if err = v4.AddComputePayloadSHA256Middleware(stack); err != nil { + if err = addResolveEndpointMiddleware(stack, options); err != nil { return err } - if err = addRetryMiddlewares(stack, options); err != nil { + if err = addComputePayloadSHA256(stack); err != nil { return err } - if err = addHTTPSignerV4Middleware(stack, options); err != nil { + if err = addRetry(stack, options); err != nil { return err } - if err = awsmiddleware.AddRawResponseToMetadata(stack); err != nil { + if err = addRawResponseToMetadata(stack); err != nil { return err } - if err = awsmiddleware.AddRecordResponseTiming(stack); err != nil { + if err = addRecordResponseTiming(stack); err != nil { return err } - if err = addClientUserAgent(stack); err != nil { + if err = addClientUserAgent(stack, options); err != nil { return err } if err = smithyhttp.AddErrorCloseResponseBodyMiddleware(stack); err != nil { @@ -132,13 +139,16 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err = smithyhttp.AddCloseResponseBodyMiddleware(stack); err != nil { return err } + if err = addSetLegacyContextSigningOptionsMiddleware(stack); err != nil { + return err + } if err = addOpUploadLayerPartValidationMiddleware(stack); err != nil { return err } if err = stack.Initialize.Add(newServiceMetadataMiddleware_opUploadLayerPart(options.Region), middleware.Before); err != nil { return err } - if err = awsmiddleware.AddRecursionDetection(stack); err != nil { + if err = addRecursionDetection(stack); err != nil { return err } if err = addRequestIDRetrieverMiddleware(stack); err != nil { @@ -150,6 +160,9 @@ func (c *Client) addOperationUploadLayerPartMiddlewares(stack *middleware.Stack, if err = addRequestResponseLogging(stack, options); err != nil { return err } + if err = addDisableHTTPSMiddleware(stack, options); err != nil { + return err + } return nil } @@ -157,7 +170,6 @@ func newServiceMetadataMiddleware_opUploadLayerPart(region string) *awsmiddlewar return &awsmiddleware.RegisterServiceMetadata{ Region: region, ServiceID: ServiceID, - SigningName: "ecr-public", OperationName: "UploadLayerPart", } } diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/auth.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/auth.go new file mode 100644 index 00000000000..80729fbc78a --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/auth.go @@ -0,0 +1,284 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package ecrpublic + +import ( + "context" + "fmt" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + smithy "github.com/aws/smithy-go" + smithyauth "github.com/aws/smithy-go/auth" + "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" +) + +func bindAuthParamsRegion(params *AuthResolverParameters, _ interface{}, options Options) { + params.Region = options.Region +} + +type setLegacyContextSigningOptionsMiddleware struct { +} + +func (*setLegacyContextSigningOptionsMiddleware) ID() string { + return "setLegacyContextSigningOptions" +} + +func (m *setLegacyContextSigningOptionsMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + rscheme := getResolvedAuthScheme(ctx) + schemeID := rscheme.Scheme.SchemeID() + + if sn := awsmiddleware.GetSigningName(ctx); sn != "" { + if schemeID == "aws.auth#sigv4" { + smithyhttp.SetSigV4SigningName(&rscheme.SignerProperties, sn) + } else if schemeID == "aws.auth#sigv4a" { + smithyhttp.SetSigV4ASigningName(&rscheme.SignerProperties, sn) + } + } + + if sr := awsmiddleware.GetSigningRegion(ctx); sr != "" { + if schemeID == "aws.auth#sigv4" { + smithyhttp.SetSigV4SigningRegion(&rscheme.SignerProperties, sr) + } else if schemeID == "aws.auth#sigv4a" { + smithyhttp.SetSigV4ASigningRegions(&rscheme.SignerProperties, []string{sr}) + } + } + + return next.HandleFinalize(ctx, in) +} + +func addSetLegacyContextSigningOptionsMiddleware(stack *middleware.Stack) error { + return stack.Finalize.Insert(&setLegacyContextSigningOptionsMiddleware{}, "Signing", middleware.Before) +} + +type withAnonymous struct { + resolver AuthSchemeResolver +} + +var _ AuthSchemeResolver = (*withAnonymous)(nil) + +func (v *withAnonymous) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { + opts, err := v.resolver.ResolveAuthSchemes(ctx, params) + if err != nil { + return nil, err + } + + opts = append(opts, &smithyauth.Option{ + SchemeID: smithyauth.SchemeIDAnonymous, + }) + return opts, nil +} + +func wrapWithAnonymousAuth(options *Options) { + if _, ok := options.AuthSchemeResolver.(*defaultAuthSchemeResolver); !ok { + return + } + + options.AuthSchemeResolver = &withAnonymous{ + resolver: options.AuthSchemeResolver, + } +} + +// AuthResolverParameters contains the set of inputs necessary for auth scheme +// resolution. +type AuthResolverParameters struct { + // The name of the operation being invoked. + Operation string + + // The region in which the operation is being invoked. + Region string +} + +func bindAuthResolverParams(operation string, input interface{}, options Options) *AuthResolverParameters { + params := &AuthResolverParameters{ + Operation: operation, + } + + bindAuthParamsRegion(params, input, options) + + return params +} + +// AuthSchemeResolver returns a set of possible authentication options for an +// operation. +type AuthSchemeResolver interface { + ResolveAuthSchemes(context.Context, *AuthResolverParameters) ([]*smithyauth.Option, error) +} + +type defaultAuthSchemeResolver struct{} + +var _ AuthSchemeResolver = (*defaultAuthSchemeResolver)(nil) + +func (*defaultAuthSchemeResolver) ResolveAuthSchemes(ctx context.Context, params *AuthResolverParameters) ([]*smithyauth.Option, error) { + if overrides, ok := operationAuthOptions[params.Operation]; ok { + return overrides(params), nil + } + return serviceAuthOptions(params), nil +} + +var operationAuthOptions = map[string]func(*AuthResolverParameters) []*smithyauth.Option{} + +func serviceAuthOptions(params *AuthResolverParameters) []*smithyauth.Option { + return []*smithyauth.Option{ + { + SchemeID: smithyauth.SchemeIDSigV4, + SignerProperties: func() smithy.Properties { + var props smithy.Properties + smithyhttp.SetSigV4SigningName(&props, "ecr-public") + smithyhttp.SetSigV4SigningRegion(&props, params.Region) + return props + }(), + }, + } +} + +type resolveAuthSchemeMiddleware struct { + operation string + options Options +} + +func (*resolveAuthSchemeMiddleware) ID() string { + return "ResolveAuthScheme" +} + +func (m *resolveAuthSchemeMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + params := bindAuthResolverParams(m.operation, getOperationInput(ctx), m.options) + options, err := m.options.AuthSchemeResolver.ResolveAuthSchemes(ctx, params) + if err != nil { + return out, metadata, fmt.Errorf("resolve auth scheme: %w", err) + } + + scheme, ok := m.selectScheme(options) + if !ok { + return out, metadata, fmt.Errorf("could not select an auth scheme") + } + + ctx = setResolvedAuthScheme(ctx, scheme) + return next.HandleFinalize(ctx, in) +} + +func (m *resolveAuthSchemeMiddleware) selectScheme(options []*smithyauth.Option) (*resolvedAuthScheme, bool) { + for _, option := range options { + if option.SchemeID == smithyauth.SchemeIDAnonymous { + return newResolvedAuthScheme(smithyhttp.NewAnonymousScheme(), option), true + } + + for _, scheme := range m.options.AuthSchemes { + if scheme.SchemeID() != option.SchemeID { + continue + } + + if scheme.IdentityResolver(m.options) != nil { + return newResolvedAuthScheme(scheme, option), true + } + } + } + + return nil, false +} + +type resolvedAuthSchemeKey struct{} + +type resolvedAuthScheme struct { + Scheme smithyhttp.AuthScheme + IdentityProperties smithy.Properties + SignerProperties smithy.Properties +} + +func newResolvedAuthScheme(scheme smithyhttp.AuthScheme, option *smithyauth.Option) *resolvedAuthScheme { + return &resolvedAuthScheme{ + Scheme: scheme, + IdentityProperties: option.IdentityProperties, + SignerProperties: option.SignerProperties, + } +} + +func setResolvedAuthScheme(ctx context.Context, scheme *resolvedAuthScheme) context.Context { + return middleware.WithStackValue(ctx, resolvedAuthSchemeKey{}, scheme) +} + +func getResolvedAuthScheme(ctx context.Context) *resolvedAuthScheme { + v, _ := middleware.GetStackValue(ctx, resolvedAuthSchemeKey{}).(*resolvedAuthScheme) + return v +} + +type getIdentityMiddleware struct { + options Options +} + +func (*getIdentityMiddleware) ID() string { + return "GetIdentity" +} + +func (m *getIdentityMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + rscheme := getResolvedAuthScheme(ctx) + if rscheme == nil { + return out, metadata, fmt.Errorf("no resolved auth scheme") + } + + resolver := rscheme.Scheme.IdentityResolver(m.options) + if resolver == nil { + return out, metadata, fmt.Errorf("no identity resolver") + } + + identity, err := resolver.GetIdentity(ctx, rscheme.IdentityProperties) + if err != nil { + return out, metadata, fmt.Errorf("get identity: %w", err) + } + + ctx = setIdentity(ctx, identity) + return next.HandleFinalize(ctx, in) +} + +type identityKey struct{} + +func setIdentity(ctx context.Context, identity smithyauth.Identity) context.Context { + return middleware.WithStackValue(ctx, identityKey{}, identity) +} + +func getIdentity(ctx context.Context) smithyauth.Identity { + v, _ := middleware.GetStackValue(ctx, identityKey{}).(smithyauth.Identity) + return v +} + +type signRequestMiddleware struct { +} + +func (*signRequestMiddleware) ID() string { + return "Signing" +} + +func (m *signRequestMiddleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + req, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, fmt.Errorf("unexpected transport type %T", in.Request) + } + + rscheme := getResolvedAuthScheme(ctx) + if rscheme == nil { + return out, metadata, fmt.Errorf("no resolved auth scheme") + } + + identity := getIdentity(ctx) + if identity == nil { + return out, metadata, fmt.Errorf("no identity") + } + + signer := rscheme.Scheme.Signer() + if signer == nil { + return out, metadata, fmt.Errorf("no signer") + } + + if err := signer.SignRequest(ctx, req, identity, rscheme.SignerProperties); err != nil { + return out, metadata, fmt.Errorf("sign request: %w", err) + } + + return next.HandleFinalize(ctx, in) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/deserializers.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/deserializers.go index 0ef759a1ca5..b6fbd266f60 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/deserializers.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/deserializers.go @@ -87,9 +87,6 @@ func awsAwsjson11_deserializeOpErrorBatchCheckLayerAvailability(response *smithy errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -97,7 +94,7 @@ func awsAwsjson11_deserializeOpErrorBatchCheckLayerAvailability(response *smithy body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -109,13 +106,12 @@ func awsAwsjson11_deserializeOpErrorBatchCheckLayerAvailability(response *smithy } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -210,9 +206,6 @@ func awsAwsjson11_deserializeOpErrorBatchDeleteImage(response *smithyhttp.Respon errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -220,7 +213,7 @@ func awsAwsjson11_deserializeOpErrorBatchDeleteImage(response *smithyhttp.Respon body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -232,13 +225,12 @@ func awsAwsjson11_deserializeOpErrorBatchDeleteImage(response *smithyhttp.Respon } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -330,9 +322,6 @@ func awsAwsjson11_deserializeOpErrorCompleteLayerUpload(response *smithyhttp.Res errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -340,7 +329,7 @@ func awsAwsjson11_deserializeOpErrorCompleteLayerUpload(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -352,13 +341,12 @@ func awsAwsjson11_deserializeOpErrorCompleteLayerUpload(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("EmptyUploadException", errorCode): return awsAwsjson11_deserializeErrorEmptyUploadException(response, errorBody) @@ -468,9 +456,6 @@ func awsAwsjson11_deserializeOpErrorCreateRepository(response *smithyhttp.Respon errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -478,7 +463,7 @@ func awsAwsjson11_deserializeOpErrorCreateRepository(response *smithyhttp.Respon body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -490,13 +475,12 @@ func awsAwsjson11_deserializeOpErrorCreateRepository(response *smithyhttp.Respon } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -597,9 +581,6 @@ func awsAwsjson11_deserializeOpErrorDeleteRepository(response *smithyhttp.Respon errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -607,7 +588,7 @@ func awsAwsjson11_deserializeOpErrorDeleteRepository(response *smithyhttp.Respon body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -619,13 +600,12 @@ func awsAwsjson11_deserializeOpErrorDeleteRepository(response *smithyhttp.Respon } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -720,9 +700,6 @@ func awsAwsjson11_deserializeOpErrorDeleteRepositoryPolicy(response *smithyhttp. errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -730,7 +707,7 @@ func awsAwsjson11_deserializeOpErrorDeleteRepositoryPolicy(response *smithyhttp. body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -742,13 +719,12 @@ func awsAwsjson11_deserializeOpErrorDeleteRepositoryPolicy(response *smithyhttp. } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -843,9 +819,6 @@ func awsAwsjson11_deserializeOpErrorDescribeImages(response *smithyhttp.Response errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -853,7 +826,7 @@ func awsAwsjson11_deserializeOpErrorDescribeImages(response *smithyhttp.Response body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -865,13 +838,12 @@ func awsAwsjson11_deserializeOpErrorDescribeImages(response *smithyhttp.Response } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("ImageNotFoundException", errorCode): return awsAwsjson11_deserializeErrorImageNotFoundException(response, errorBody) @@ -966,9 +938,6 @@ func awsAwsjson11_deserializeOpErrorDescribeImageTags(response *smithyhttp.Respo errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -976,7 +945,7 @@ func awsAwsjson11_deserializeOpErrorDescribeImageTags(response *smithyhttp.Respo body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -988,13 +957,12 @@ func awsAwsjson11_deserializeOpErrorDescribeImageTags(response *smithyhttp.Respo } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -1086,9 +1054,6 @@ func awsAwsjson11_deserializeOpErrorDescribeRegistries(response *smithyhttp.Resp errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1096,7 +1061,7 @@ func awsAwsjson11_deserializeOpErrorDescribeRegistries(response *smithyhttp.Resp body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1108,13 +1073,12 @@ func awsAwsjson11_deserializeOpErrorDescribeRegistries(response *smithyhttp.Resp } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -1203,9 +1167,6 @@ func awsAwsjson11_deserializeOpErrorDescribeRepositories(response *smithyhttp.Re errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1213,7 +1174,7 @@ func awsAwsjson11_deserializeOpErrorDescribeRepositories(response *smithyhttp.Re body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1225,13 +1186,12 @@ func awsAwsjson11_deserializeOpErrorDescribeRepositories(response *smithyhttp.Re } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -1323,9 +1283,6 @@ func awsAwsjson11_deserializeOpErrorGetAuthorizationToken(response *smithyhttp.R errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1333,7 +1290,7 @@ func awsAwsjson11_deserializeOpErrorGetAuthorizationToken(response *smithyhttp.R body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1345,13 +1302,12 @@ func awsAwsjson11_deserializeOpErrorGetAuthorizationToken(response *smithyhttp.R } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -1440,9 +1396,6 @@ func awsAwsjson11_deserializeOpErrorGetRegistryCatalogData(response *smithyhttp. errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1450,7 +1403,7 @@ func awsAwsjson11_deserializeOpErrorGetRegistryCatalogData(response *smithyhttp. body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1462,13 +1415,12 @@ func awsAwsjson11_deserializeOpErrorGetRegistryCatalogData(response *smithyhttp. } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("ServerException", errorCode): return awsAwsjson11_deserializeErrorServerException(response, errorBody) @@ -1554,9 +1506,6 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryCatalogData(response *smithyhtt errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1564,7 +1513,7 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryCatalogData(response *smithyhtt body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1576,13 +1525,12 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryCatalogData(response *smithyhtt } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -1677,9 +1625,6 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryPolicy(response *smithyhttp.Res errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1687,7 +1632,7 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryPolicy(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1699,13 +1644,12 @@ func awsAwsjson11_deserializeOpErrorGetRepositoryPolicy(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -1800,9 +1744,6 @@ func awsAwsjson11_deserializeOpErrorInitiateLayerUpload(response *smithyhttp.Res errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1810,7 +1751,7 @@ func awsAwsjson11_deserializeOpErrorInitiateLayerUpload(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1822,13 +1763,12 @@ func awsAwsjson11_deserializeOpErrorInitiateLayerUpload(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -1923,9 +1863,6 @@ func awsAwsjson11_deserializeOpErrorListTagsForResource(response *smithyhttp.Res errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -1933,7 +1870,7 @@ func awsAwsjson11_deserializeOpErrorListTagsForResource(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -1945,13 +1882,12 @@ func awsAwsjson11_deserializeOpErrorListTagsForResource(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2043,9 +1979,6 @@ func awsAwsjson11_deserializeOpErrorPutImage(response *smithyhttp.Response, meta errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2053,7 +1986,7 @@ func awsAwsjson11_deserializeOpErrorPutImage(response *smithyhttp.Response, meta body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2065,13 +1998,12 @@ func awsAwsjson11_deserializeOpErrorPutImage(response *smithyhttp.Response, meta } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("ImageAlreadyExistsException", errorCode): return awsAwsjson11_deserializeErrorImageAlreadyExistsException(response, errorBody) @@ -2184,9 +2116,6 @@ func awsAwsjson11_deserializeOpErrorPutRegistryCatalogData(response *smithyhttp. errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2194,7 +2123,7 @@ func awsAwsjson11_deserializeOpErrorPutRegistryCatalogData(response *smithyhttp. body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2206,13 +2135,12 @@ func awsAwsjson11_deserializeOpErrorPutRegistryCatalogData(response *smithyhttp. } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2301,9 +2229,6 @@ func awsAwsjson11_deserializeOpErrorPutRepositoryCatalogData(response *smithyhtt errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2311,7 +2236,7 @@ func awsAwsjson11_deserializeOpErrorPutRepositoryCatalogData(response *smithyhtt body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2323,13 +2248,12 @@ func awsAwsjson11_deserializeOpErrorPutRepositoryCatalogData(response *smithyhtt } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2421,9 +2345,6 @@ func awsAwsjson11_deserializeOpErrorSetRepositoryPolicy(response *smithyhttp.Res errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2431,7 +2352,7 @@ func awsAwsjson11_deserializeOpErrorSetRepositoryPolicy(response *smithyhttp.Res body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2443,13 +2364,12 @@ func awsAwsjson11_deserializeOpErrorSetRepositoryPolicy(response *smithyhttp.Res } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2541,9 +2461,6 @@ func awsAwsjson11_deserializeOpErrorTagResource(response *smithyhttp.Response, m errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2551,7 +2468,7 @@ func awsAwsjson11_deserializeOpErrorTagResource(response *smithyhttp.Response, m body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2563,13 +2480,12 @@ func awsAwsjson11_deserializeOpErrorTagResource(response *smithyhttp.Response, m } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2667,9 +2583,6 @@ func awsAwsjson11_deserializeOpErrorUntagResource(response *smithyhttp.Response, errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2677,7 +2590,7 @@ func awsAwsjson11_deserializeOpErrorUntagResource(response *smithyhttp.Response, body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2689,13 +2602,12 @@ func awsAwsjson11_deserializeOpErrorUntagResource(response *smithyhttp.Response, } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidParameterException", errorCode): return awsAwsjson11_deserializeErrorInvalidParameterException(response, errorBody) @@ -2793,9 +2705,6 @@ func awsAwsjson11_deserializeOpErrorUploadLayerPart(response *smithyhttp.Respons errorMessage := errorCode headerCode := response.Header.Get("X-Amzn-ErrorType") - if len(headerCode) != 0 { - errorCode = restjson.SanitizeErrorCode(headerCode) - } var buff [1024]byte ringBuffer := smithyio.NewRingBuffer(buff[:]) @@ -2803,7 +2712,7 @@ func awsAwsjson11_deserializeOpErrorUploadLayerPart(response *smithyhttp.Respons body := io.TeeReader(errorBody, ringBuffer) decoder := json.NewDecoder(body) decoder.UseNumber() - jsonCode, message, err := restjson.GetErrorInfo(decoder) + bodyInfo, err := getProtocolErrorInfo(decoder) if err != nil { var snapshot bytes.Buffer io.Copy(&snapshot, ringBuffer) @@ -2815,13 +2724,12 @@ func awsAwsjson11_deserializeOpErrorUploadLayerPart(response *smithyhttp.Respons } errorBody.Seek(0, io.SeekStart) - if len(headerCode) == 0 && len(jsonCode) != 0 { - errorCode = restjson.SanitizeErrorCode(jsonCode) + if typ, ok := resolveProtocolErrorType(headerCode, bodyInfo); ok { + errorCode = restjson.SanitizeErrorCode(typ) } - if len(message) != 0 { - errorMessage = message + if len(bodyInfo.Message) != 0 { + errorMessage = bodyInfo.Message } - switch { case strings.EqualFold("InvalidLayerPartException", errorCode): return awsAwsjson11_deserializeErrorInvalidLayerPartException(response, errorBody) @@ -7177,3 +7085,32 @@ func awsAwsjson11_deserializeOpDocumentUploadLayerPartOutput(v **UploadLayerPart *v = sv return nil } + +type protocolErrorInfo struct { + Type string `json:"__type"` + Message string + Code any // nonstandard for awsjson but some services do present the type here +} + +func getProtocolErrorInfo(decoder *json.Decoder) (protocolErrorInfo, error) { + var errInfo protocolErrorInfo + if err := decoder.Decode(&errInfo); err != nil { + if err == io.EOF { + return errInfo, nil + } + return errInfo, err + } + + return errInfo, nil +} + +func resolveProtocolErrorType(headerType string, bodyInfo protocolErrorInfo) (string, bool) { + if len(headerType) != 0 { + return headerType, true + } else if len(bodyInfo.Type) != 0 { + return bodyInfo.Type, true + } else if code, ok := bodyInfo.Code.(string); ok && len(code) != 0 { + return code, true + } + return "", false +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/endpoints.go index 071eca69cbb..95e0c365a3c 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/endpoints.go @@ -8,10 +8,18 @@ import ( "fmt" "github.com/aws/aws-sdk-go-v2/aws" awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalConfig "github.com/aws/aws-sdk-go-v2/internal/configsources" + "github.com/aws/aws-sdk-go-v2/internal/endpoints" + "github.com/aws/aws-sdk-go-v2/internal/endpoints/awsrulesfn" internalendpoints "github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints" + smithyauth "github.com/aws/smithy-go/auth" + smithyendpoints "github.com/aws/smithy-go/endpoints" "github.com/aws/smithy-go/middleware" + "github.com/aws/smithy-go/ptr" smithyhttp "github.com/aws/smithy-go/transport/http" + "net/http" "net/url" + "os" "strings" ) @@ -39,13 +47,6 @@ func (fn EndpointResolverFunc) ResolveEndpoint(region string, options EndpointRe return fn(region, options) } -func resolveDefaultEndpointConfiguration(o *Options) { - if o.EndpointResolver != nil { - return - } - o.EndpointResolver = NewDefaultEndpointResolver() -} - // EndpointResolverFromURL returns an EndpointResolver configured using the // provided endpoint url. By default, the resolved endpoint resolver uses the // client region as signing region, and the endpoint source is set to @@ -79,6 +80,10 @@ func (*ResolveEndpoint) ID() string { func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.SerializeInput, next middleware.SerializeHandler) ( out middleware.SerializeOutput, metadata middleware.Metadata, err error, ) { + if !awsmiddleware.GetRequiresLegacyEndpoints(ctx) { + return next.HandleSerialize(ctx, in) + } + req, ok := in.Request.(*smithyhttp.Request) if !ok { return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) @@ -94,6 +99,11 @@ func (m *ResolveEndpoint) HandleSerialize(ctx context.Context, in middleware.Ser var endpoint aws.Endpoint endpoint, err = m.Resolver.ResolveEndpoint(awsmiddleware.GetRegion(ctx), eo) if err != nil { + nf := (&aws.EndpointNotFoundError{}) + if errors.As(err, &nf) { + ctx = awsmiddleware.SetRequiresLegacyEndpoints(ctx, false) + return next.HandleSerialize(ctx, in) + } return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) } @@ -129,27 +139,10 @@ func removeResolveEndpointMiddleware(stack *middleware.Stack) error { type wrappedEndpointResolver struct { awsResolver aws.EndpointResolverWithOptions - resolver EndpointResolver } func (w *wrappedEndpointResolver) ResolveEndpoint(region string, options EndpointResolverOptions) (endpoint aws.Endpoint, err error) { - if w.awsResolver == nil { - goto fallback - } - endpoint, err = w.awsResolver.ResolveEndpoint(ServiceID, region, options) - if err == nil { - return endpoint, nil - } - - if nf := (&aws.EndpointNotFoundError{}); !errors.As(err, &nf) { - return endpoint, err - } - -fallback: - if w.resolver == nil { - return endpoint, fmt.Errorf("default endpoint resolver provided was nil") - } - return w.resolver.ResolveEndpoint(region, options) + return w.awsResolver.ResolveEndpoint(ServiceID, region, options) } type awsEndpointResolverAdaptor func(service, region string) (aws.Endpoint, error) @@ -160,12 +153,13 @@ func (a awsEndpointResolverAdaptor) ResolveEndpoint(service, region string, opti var _ aws.EndpointResolverWithOptions = awsEndpointResolverAdaptor(nil) -// withEndpointResolver returns an EndpointResolver that first delegates endpoint resolution to the awsResolver. -// If awsResolver returns aws.EndpointNotFoundError error, the resolver will use the the provided -// fallbackResolver for resolution. +// withEndpointResolver returns an aws.EndpointResolverWithOptions that first delegates endpoint resolution to the awsResolver. +// If awsResolver returns aws.EndpointNotFoundError error, the v1 resolver middleware will swallow the error, +// and set an appropriate context flag such that fallback will occur when EndpointResolverV2 is invoked +// via its middleware. // -// fallbackResolver must not be nil -func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions, fallbackResolver EndpointResolver) EndpointResolver { +// If another error (besides aws.EndpointNotFoundError) is returned, then that error will be propagated. +func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptions aws.EndpointResolverWithOptions) EndpointResolver { var resolver aws.EndpointResolverWithOptions if awsResolverWithOptions != nil { @@ -176,7 +170,6 @@ func withEndpointResolver(awsResolver aws.EndpointResolver, awsResolverWithOptio return &wrappedEndpointResolver{ awsResolver: resolver, - resolver: fallbackResolver, } } @@ -198,3 +191,326 @@ func finalizeClientEndpointResolverOptions(options *Options) { } } + +func resolveEndpointResolverV2(options *Options) { + if options.EndpointResolverV2 == nil { + options.EndpointResolverV2 = NewDefaultEndpointResolverV2() + } +} + +func resolveBaseEndpoint(cfg aws.Config, o *Options) { + if cfg.BaseEndpoint != nil { + o.BaseEndpoint = cfg.BaseEndpoint + } + + _, g := os.LookupEnv("AWS_ENDPOINT_URL") + _, s := os.LookupEnv("AWS_ENDPOINT_URL_ECR_PUBLIC") + + if g && !s { + return + } + + value, found, err := internalConfig.ResolveServiceBaseEndpoint(context.Background(), "ECR PUBLIC", cfg.ConfigSources) + if found && err == nil { + o.BaseEndpoint = &value + } +} + +func bindRegion(region string) *string { + if region == "" { + return nil + } + return aws.String(endpoints.MapFIPSRegion(region)) +} + +// EndpointParameters provides the parameters that influence how endpoints are +// resolved. +type EndpointParameters struct { + // The AWS region used to dispatch the request. + // + // Parameter is + // required. + // + // AWS::Region + Region *string + + // When true, use the dual-stack endpoint. If the configured endpoint does not + // support dual-stack, dispatching the request MAY return an error. + // + // Defaults to + // false if no value is provided. + // + // AWS::UseDualStack + UseDualStack *bool + + // When true, send this request to the FIPS-compliant regional endpoint. If the + // configured endpoint does not have a FIPS compliant endpoint, dispatching the + // request will return an error. + // + // Defaults to false if no value is + // provided. + // + // AWS::UseFIPS + UseFIPS *bool + + // Override the endpoint used to send this request + // + // Parameter is + // required. + // + // SDK::Endpoint + Endpoint *string +} + +// ValidateRequired validates required parameters are set. +func (p EndpointParameters) ValidateRequired() error { + if p.UseDualStack == nil { + return fmt.Errorf("parameter UseDualStack is required") + } + + if p.UseFIPS == nil { + return fmt.Errorf("parameter UseFIPS is required") + } + + return nil +} + +// WithDefaults returns a shallow copy of EndpointParameterswith default values +// applied to members where applicable. +func (p EndpointParameters) WithDefaults() EndpointParameters { + if p.UseDualStack == nil { + p.UseDualStack = ptr.Bool(false) + } + + if p.UseFIPS == nil { + p.UseFIPS = ptr.Bool(false) + } + return p +} + +// EndpointResolverV2 provides the interface for resolving service endpoints. +type EndpointResolverV2 interface { + // ResolveEndpoint attempts to resolve the endpoint with the provided options, + // returning the endpoint if found. Otherwise an error is returned. + ResolveEndpoint(ctx context.Context, params EndpointParameters) ( + smithyendpoints.Endpoint, error, + ) +} + +// resolver provides the implementation for resolving endpoints. +type resolver struct{} + +func NewDefaultEndpointResolverV2() EndpointResolverV2 { + return &resolver{} +} + +// ResolveEndpoint attempts to resolve the endpoint with the provided options, +// returning the endpoint if found. Otherwise an error is returned. +func (r *resolver) ResolveEndpoint( + ctx context.Context, params EndpointParameters, +) ( + endpoint smithyendpoints.Endpoint, err error, +) { + params = params.WithDefaults() + if err = params.ValidateRequired(); err != nil { + return endpoint, fmt.Errorf("endpoint parameters are not valid, %w", err) + } + _UseDualStack := *params.UseDualStack + _UseFIPS := *params.UseFIPS + + if exprVal := params.Endpoint; exprVal != nil { + _Endpoint := *exprVal + _ = _Endpoint + if _UseFIPS == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: FIPS and custom endpoint are not supported") + } + if _UseDualStack == true { + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Dualstack and custom endpoint are not supported") + } + uriString := _Endpoint + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + if exprVal := params.Region; exprVal != nil { + _Region := *exprVal + _ = _Region + if exprVal := awsrulesfn.GetPartition(_Region); exprVal != nil { + _PartitionResult := *exprVal + _ = _PartitionResult + if _UseFIPS == true { + if _UseDualStack == true { + if true == _PartitionResult.SupportsFIPS { + if true == _PartitionResult.SupportsDualStack { + uriString := func() string { + var out strings.Builder + out.WriteString("https://api.ecr-public-fips.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_PartitionResult.DualStackDnsSuffix) + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS and DualStack are enabled, but this partition does not support one or both") + } + } + if _UseFIPS == true { + if true == _PartitionResult.SupportsFIPS { + uriString := func() string { + var out strings.Builder + out.WriteString("https://api.ecr-public-fips.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_PartitionResult.DnsSuffix) + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "FIPS is enabled but this partition does not support FIPS") + } + if _UseDualStack == true { + if true == _PartitionResult.SupportsDualStack { + uriString := func() string { + var out strings.Builder + out.WriteString("https://api.ecr-public.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_PartitionResult.DualStackDnsSuffix) + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "DualStack is enabled but this partition does not support DualStack") + } + uriString := func() string { + var out strings.Builder + out.WriteString("https://api.ecr-public.") + out.WriteString(_Region) + out.WriteString(".") + out.WriteString(_PartitionResult.DnsSuffix) + return out.String() + }() + + uri, err := url.Parse(uriString) + if err != nil { + return endpoint, fmt.Errorf("Failed to parse uri: %s", uriString) + } + + return smithyendpoints.Endpoint{ + URI: *uri, + Headers: http.Header{}, + }, nil + } + return endpoint, fmt.Errorf("Endpoint resolution failed. Invalid operation or environment input.") + } + return endpoint, fmt.Errorf("endpoint rule error, %s", "Invalid Configuration: Missing Region") +} + +type endpointParamsBinder interface { + bindEndpointParams(*EndpointParameters) +} + +func bindEndpointParams(input interface{}, options Options) *EndpointParameters { + params := &EndpointParameters{} + + params.Region = bindRegion(options.Region) + params.UseDualStack = aws.Bool(options.EndpointOptions.UseDualStackEndpoint == aws.DualStackEndpointStateEnabled) + params.UseFIPS = aws.Bool(options.EndpointOptions.UseFIPSEndpoint == aws.FIPSEndpointStateEnabled) + params.Endpoint = options.BaseEndpoint + + if b, ok := input.(endpointParamsBinder); ok { + b.bindEndpointParams(params) + } + + return params +} + +type resolveEndpointV2Middleware struct { + options Options +} + +func (*resolveEndpointV2Middleware) ID() string { + return "ResolveEndpointV2" +} + +func (m *resolveEndpointV2Middleware) HandleFinalize(ctx context.Context, in middleware.FinalizeInput, next middleware.FinalizeHandler) ( + out middleware.FinalizeOutput, metadata middleware.Metadata, err error, +) { + if awsmiddleware.GetRequiresLegacyEndpoints(ctx) { + return next.HandleFinalize(ctx, in) + } + + req, ok := in.Request.(*smithyhttp.Request) + if !ok { + return out, metadata, fmt.Errorf("unknown transport type %T", in.Request) + } + + if m.options.EndpointResolverV2 == nil { + return out, metadata, fmt.Errorf("expected endpoint resolver to not be nil") + } + + params := bindEndpointParams(getOperationInput(ctx), m.options) + endpt, err := m.options.EndpointResolverV2.ResolveEndpoint(ctx, *params) + if err != nil { + return out, metadata, fmt.Errorf("failed to resolve service endpoint, %w", err) + } + + if endpt.URI.RawPath == "" && req.URL.RawPath != "" { + endpt.URI.RawPath = endpt.URI.Path + } + req.URL.Scheme = endpt.URI.Scheme + req.URL.Host = endpt.URI.Host + req.URL.Path = smithyhttp.JoinPath(endpt.URI.Path, req.URL.Path) + req.URL.RawPath = smithyhttp.JoinPath(endpt.URI.RawPath, req.URL.RawPath) + for k := range endpt.Headers { + req.Header.Set(k, endpt.Headers.Get(k)) + } + + rscheme := getResolvedAuthScheme(ctx) + if rscheme == nil { + return out, metadata, fmt.Errorf("no resolved auth scheme") + } + + opts, _ := smithyauth.GetAuthOptions(&endpt.Properties) + for _, o := range opts { + rscheme.SignerProperties.SetAll(&o.SignerProperties) + } + + return next.HandleFinalize(ctx, in) +} diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/generated.json b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/generated.json index a60655a86d5..f11524a5feb 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/generated.json +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/generated.json @@ -31,14 +31,19 @@ "api_op_TagResource.go", "api_op_UntagResource.go", "api_op_UploadLayerPart.go", + "auth.go", "deserializers.go", "doc.go", "endpoints.go", + "endpoints_config_test.go", + "endpoints_test.go", "generated.json", "internal/endpoints/endpoints.go", "internal/endpoints/endpoints_test.go", + "options.go", "protocol_test.go", "serializers.go", + "snapshot_test.go", "types/enums.go", "types/errors.go", "types/types.go", diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/go_module_metadata.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/go_module_metadata.go index 70b89eb7633..6bb90d74a0b 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/go_module_metadata.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/go_module_metadata.go @@ -3,4 +3,4 @@ package ecrpublic // goModuleVersion is the tagged release for this module -const goModuleVersion = "1.16.2" +const goModuleVersion = "1.23.3" diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints/endpoints.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints/endpoints.go index 0f540b2c2d2..7f122295985 100644 --- a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints/endpoints.go +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints/endpoints.go @@ -90,14 +90,16 @@ var partitionRegexp = struct { AwsIso *regexp.Regexp AwsIsoB *regexp.Regexp AwsIsoE *regexp.Regexp + AwsIsoF *regexp.Regexp AwsUsGov *regexp.Regexp }{ - Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af)\\-\\w+\\-\\d+$"), + Aws: regexp.MustCompile("^(us|eu|ap|sa|ca|me|af|il)\\-\\w+\\-\\d+$"), AwsCn: regexp.MustCompile("^cn\\-\\w+\\-\\d+$"), AwsIso: regexp.MustCompile("^us\\-iso\\-\\w+\\-\\d+$"), AwsIsoB: regexp.MustCompile("^us\\-isob\\-\\w+\\-\\d+$"), AwsIsoE: regexp.MustCompile("^eu\\-isoe\\-\\w+\\-\\d+$"), + AwsIsoF: regexp.MustCompile("^us\\-isof\\-\\w+\\-\\d+$"), AwsUsGov: regexp.MustCompile("^us\\-gov\\-\\w+\\-\\d+$"), } @@ -253,6 +255,27 @@ var defaultPartitions = endpoints.Partitions{ RegionRegex: partitionRegexp.AwsIsoE, IsRegionalized: true, }, + { + ID: "aws-iso-f", + Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ + { + Variant: endpoints.FIPSVariant, + }: { + Hostname: "api.ecr-public-fips.{region}.csp.hci.ic.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + { + Variant: 0, + }: { + Hostname: "api.ecr-public.{region}.csp.hci.ic.gov", + Protocols: []string{"https"}, + SignatureVersions: []string{"v4"}, + }, + }, + RegionRegex: partitionRegexp.AwsIsoF, + IsRegionalized: true, + }, { ID: "aws-us-gov", Defaults: map[endpoints.DefaultKey]endpoints.Endpoint{ diff --git a/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/options.go b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/options.go new file mode 100644 index 00000000000..2845b43a8dd --- /dev/null +++ b/vendor/github.com/aws/aws-sdk-go-v2/service/ecrpublic/options.go @@ -0,0 +1,217 @@ +// Code generated by smithy-go-codegen DO NOT EDIT. + +package ecrpublic + +import ( + "context" + "github.com/aws/aws-sdk-go-v2/aws" + awsmiddleware "github.com/aws/aws-sdk-go-v2/aws/middleware" + internalauthsmithy "github.com/aws/aws-sdk-go-v2/internal/auth/smithy" + smithyauth "github.com/aws/smithy-go/auth" + "github.com/aws/smithy-go/logging" + "github.com/aws/smithy-go/middleware" + smithyhttp "github.com/aws/smithy-go/transport/http" + "net/http" +) + +type HTTPClient interface { + Do(*http.Request) (*http.Response, error) +} + +type Options struct { + // Set of options to modify how an operation is invoked. These apply to all + // operations invoked for this client. Use functional options on operation call to + // modify this list for per operation behavior. + APIOptions []func(*middleware.Stack) error + + // The optional application specific identifier appended to the User-Agent header. + AppID string + + // This endpoint will be given as input to an EndpointResolverV2. It is used for + // providing a custom base endpoint that is subject to modifications by the + // processing EndpointResolverV2. + BaseEndpoint *string + + // Configures the events that will be sent to the configured logger. + ClientLogMode aws.ClientLogMode + + // The credentials object to use when signing requests. + Credentials aws.CredentialsProvider + + // The configuration DefaultsMode that the SDK should use when constructing the + // clients initial default settings. + DefaultsMode aws.DefaultsMode + + // The endpoint options to be used when attempting to resolve an endpoint. + EndpointOptions EndpointResolverOptions + + // The service endpoint resolver. + // + // Deprecated: Deprecated: EndpointResolver and WithEndpointResolver. Providing a + // value for this field will likely prevent you from using any endpoint-related + // service features released after the introduction of EndpointResolverV2 and + // BaseEndpoint. To migrate an EndpointResolver implementation that uses a custom + // endpoint, set the client option BaseEndpoint instead. + EndpointResolver EndpointResolver + + // Resolves the endpoint used for a particular service operation. This should be + // used over the deprecated EndpointResolver. + EndpointResolverV2 EndpointResolverV2 + + // Signature Version 4 (SigV4) Signer + HTTPSignerV4 HTTPSignerV4 + + // The logger writer interface to write logging messages to. + Logger logging.Logger + + // The region to send requests to. (Required) + Region string + + // RetryMaxAttempts specifies the maximum number attempts an API client will call + // an operation that fails with a retryable error. A value of 0 is ignored, and + // will not be used to configure the API client created default retryer, or modify + // per operation call's retry max attempts. If specified in an operation call's + // functional options with a value that is different than the constructed client's + // Options, the Client's Retryer will be wrapped to use the operation's specific + // RetryMaxAttempts value. + RetryMaxAttempts int + + // RetryMode specifies the retry mode the API client will be created with, if + // Retryer option is not also specified. When creating a new API Clients this + // member will only be used if the Retryer Options member is nil. This value will + // be ignored if Retryer is not nil. Currently does not support per operation call + // overrides, may in the future. + RetryMode aws.RetryMode + + // Retryer guides how HTTP requests should be retried in case of recoverable + // failures. When nil the API client will use a default retryer. The kind of + // default retry created by the API client can be changed with the RetryMode + // option. + Retryer aws.Retryer + + // The RuntimeEnvironment configuration, only populated if the DefaultsMode is set + // to DefaultsModeAuto and is initialized using config.LoadDefaultConfig . You + // should not populate this structure programmatically, or rely on the values here + // within your applications. + RuntimeEnvironment aws.RuntimeEnvironment + + // The initial DefaultsMode used when the client options were constructed. If the + // DefaultsMode was set to aws.DefaultsModeAuto this will store what the resolved + // value was at that point in time. Currently does not support per operation call + // overrides, may in the future. + resolvedDefaultsMode aws.DefaultsMode + + // The HTTP client to invoke API calls with. Defaults to client's default HTTP + // implementation if nil. + HTTPClient HTTPClient + + // The auth scheme resolver which determines how to authenticate for each + // operation. + AuthSchemeResolver AuthSchemeResolver + + // The list of auth schemes supported by the client. + AuthSchemes []smithyhttp.AuthScheme +} + +// Copy creates a clone where the APIOptions list is deep copied. +func (o Options) Copy() Options { + to := o + to.APIOptions = make([]func(*middleware.Stack) error, len(o.APIOptions)) + copy(to.APIOptions, o.APIOptions) + + return to +} + +func (o Options) GetIdentityResolver(schemeID string) smithyauth.IdentityResolver { + if schemeID == "aws.auth#sigv4" { + return getSigV4IdentityResolver(o) + } + if schemeID == "smithy.api#noAuth" { + return &smithyauth.AnonymousIdentityResolver{} + } + return nil +} + +// WithAPIOptions returns a functional option for setting the Client's APIOptions +// option. +func WithAPIOptions(optFns ...func(*middleware.Stack) error) func(*Options) { + return func(o *Options) { + o.APIOptions = append(o.APIOptions, optFns...) + } +} + +// Deprecated: EndpointResolver and WithEndpointResolver. Providing a value for +// this field will likely prevent you from using any endpoint-related service +// features released after the introduction of EndpointResolverV2 and BaseEndpoint. +// To migrate an EndpointResolver implementation that uses a custom endpoint, set +// the client option BaseEndpoint instead. +func WithEndpointResolver(v EndpointResolver) func(*Options) { + return func(o *Options) { + o.EndpointResolver = v + } +} + +// WithEndpointResolverV2 returns a functional option for setting the Client's +// EndpointResolverV2 option. +func WithEndpointResolverV2(v EndpointResolverV2) func(*Options) { + return func(o *Options) { + o.EndpointResolverV2 = v + } +} + +func getSigV4IdentityResolver(o Options) smithyauth.IdentityResolver { + if o.Credentials != nil { + return &internalauthsmithy.CredentialsProviderAdapter{Provider: o.Credentials} + } + return nil +} + +// WithSigV4SigningName applies an override to the authentication workflow to +// use the given signing name for SigV4-authenticated operations. +// +// This is an advanced setting. The value here is FINAL, taking precedence over +// the resolved signing name from both auth scheme resolution and endpoint +// resolution. +func WithSigV4SigningName(name string) func(*Options) { + fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, + ) { + return next.HandleInitialize(awsmiddleware.SetSigningName(ctx, name), in) + } + return func(o *Options) { + o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error { + return s.Initialize.Add( + middleware.InitializeMiddlewareFunc("withSigV4SigningName", fn), + middleware.Before, + ) + }) + } +} + +// WithSigV4SigningRegion applies an override to the authentication workflow to +// use the given signing region for SigV4-authenticated operations. +// +// This is an advanced setting. The value here is FINAL, taking precedence over +// the resolved signing region from both auth scheme resolution and endpoint +// resolution. +func WithSigV4SigningRegion(region string) func(*Options) { + fn := func(ctx context.Context, in middleware.InitializeInput, next middleware.InitializeHandler) ( + out middleware.InitializeOutput, metadata middleware.Metadata, err error, + ) { + return next.HandleInitialize(awsmiddleware.SetSigningRegion(ctx, region), in) + } + return func(o *Options) { + o.APIOptions = append(o.APIOptions, func(s *middleware.Stack) error { + return s.Initialize.Add( + middleware.InitializeMiddlewareFunc("withSigV4SigningRegion", fn), + middleware.Before, + ) + }) + } +} + +func ignoreAnonymousAuth(options *Options) { + if aws.IsCredentialsProvider(options.Credentials, (*aws.AnonymousCredentials)(nil)) { + options.Credentials = nil + } +} diff --git a/vendor/modules.txt b/vendor/modules.txt index e86bbbe274e..b16ddca7c4f 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -204,13 +204,13 @@ github.com/aws/aws-sdk-go-v2/internal/endpoints/v2 # github.com/aws/aws-sdk-go-v2/internal/ini v1.8.0 ## explicit; go 1.20 github.com/aws/aws-sdk-go-v2/internal/ini -# github.com/aws/aws-sdk-go-v2/service/ecr v1.18.11 -## explicit; go 1.15 +# github.com/aws/aws-sdk-go-v2/service/ecr v1.18.11 => github.com/aws/aws-sdk-go-v2/service/ecr v1.27.3 +## explicit; go 1.20 github.com/aws/aws-sdk-go-v2/service/ecr github.com/aws/aws-sdk-go-v2/service/ecr/internal/endpoints github.com/aws/aws-sdk-go-v2/service/ecr/types -# github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.16.2 -## explicit; go 1.15 +# github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.16.2 => github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.23.3 +## explicit; go 1.20 github.com/aws/aws-sdk-go-v2/service/ecrpublic github.com/aws/aws-sdk-go-v2/service/ecrpublic/internal/endpoints github.com/aws/aws-sdk-go-v2/service/ecrpublic/types @@ -1911,4 +1911,6 @@ sigs.k8s.io/yaml/goyaml.v2 # k8s.io/apimachinery => k8s.io/apimachinery v0.28.5 # k8s.io/client-go => k8s.io/client-go v0.28.5 # k8s.io/code-generator => k8s.io/code-generator v0.28.5 +# github.com/aws/aws-sdk-go-v2/service/ecr => github.com/aws/aws-sdk-go-v2/service/ecr v1.27.3 +# github.com/aws/aws-sdk-go-v2/service/ecrpublic => github.com/aws/aws-sdk-go-v2/service/ecrpublic v1.23.3 # github.com/ahmetb/gen-crd-api-reference-docs => github.com/tektoncd/ahmetb-gen-crd-api-reference-docs v0.3.1-0.20220729140133-6ce2d5aafcb4 From 88fc7401d64f9e0a5549a917c1e82f2e972e11ba Mon Sep 17 00:00:00 2001 From: Chitrang Patel Date: Mon, 8 Apr 2024 09:11:10 -0400 Subject: [PATCH 11/23] TEP0154 - Enable concise resolver syntax This PR enables concise resolver syntax interface. --- config/config-feature-flags.yaml | 2 + docs/how-to-write-a-resolver.md | 22 ++- docs/pipeline-api.md | 32 ++++ docs/resolver-template/cmd/resolver/main.go | 9 ++ .../cmd/resolver/main_test.go | 142 +++++++++++++++++- pkg/apis/config/feature_flags.go | 39 +++-- pkg/apis/config/feature_flags_test.go | 5 + .../testdata/feature-flags-all-flags-set.yaml | 1 + ...nvalid-enable-concise-resolver-syntax.yaml | 21 +++ pkg/apis/pipeline/v1/container_validation.go | 78 +++++++--- .../pipeline/v1/container_validation_test.go | 50 ++++-- pkg/apis/pipeline/v1/pipeline_types_test.go | 51 ++++++- .../pipeline/v1/pipelineref_validation.go | 26 +--- .../v1/pipelineref_validation_test.go | 51 +++++-- pkg/apis/pipeline/v1/taskref_validation.go | 32 +--- .../pipeline/v1/taskref_validation_test.go | 42 ++++-- .../pipeline/v1beta1/container_validation.go | 78 +++++++--- .../v1beta1/container_validation_test.go | 52 +++++-- .../pipeline/v1beta1/openapi_generated.go | 7 + .../pipeline/v1beta1/pipeline_types_test.go | 51 ++++++- .../v1beta1/pipelineref_validation.go | 61 ++++++-- .../v1beta1/pipelineref_validation_test.go | 55 ++++--- pkg/apis/pipeline/v1beta1/swagger.json | 4 + .../pipeline/v1beta1/taskref_validation.go | 56 ++++--- .../v1beta1/taskref_validation_test.go | 48 +++--- .../v1beta1/resolution_request_types.go | 7 + .../pipelinerun/pipelinerun_test.go | 2 +- pkg/reconciler/pipelinerun/resources/apply.go | 28 +++- .../pipelinerun/resources/pipelineref.go | 10 +- .../pipelinerun/resources/pipelineref_test.go | 2 + pkg/reconciler/taskrun/resources/taskref.go | 9 ++ .../taskrun/resources/taskref_test.go | 2 + pkg/reconciler/taskrun/taskrun_test.go | 2 +- .../resolver/bundle/resolver.go | 15 +- .../resolver/cluster/resolver.go | 15 +- .../resolver/framework/fakeresolver.go | 20 ++- .../resolver/framework/reconciler_test.go | 136 +++++++++++++++++ pkg/remoteresolution/resolver/git/resolver.go | 34 +++-- .../resolver/http/resolver.go | 30 ++-- .../resolver/http/resolver_test.go | 12 +- pkg/remoteresolution/resolver/hub/resolver.go | 13 +- pkg/remoteresolution/resource/crd_resource.go | 1 + .../resource/crd_resource_test.go | 2 + pkg/remoteresolution/resource/request_test.go | 1 + pkg/resolution/resource/name.go | 5 + pkg/resolution/resource/name_test.go | 105 +++++++++++++ test/e2e-tests-kind-prow-alpha.env | 1 + test/e2e-tests.sh | 14 ++ test/featureflags.go | 15 +- test/remoteresolution/resolution.go | 7 +- 50 files changed, 1196 insertions(+), 307 deletions(-) create mode 100644 pkg/apis/config/testdata/feature-flags-invalid-enable-concise-resolver-syntax.yaml diff --git a/config/config-feature-flags.yaml b/config/config-feature-flags.yaml index bea6994cc99..26a97d523b7 100644 --- a/config/config-feature-flags.yaml +++ b/config/config-feature-flags.yaml @@ -137,3 +137,5 @@ data: # "pipelinerun" for Pipelinerun and "taskrun" for Taskrun. Or a combination of # these. disable-inline-spec: "" + # Setting this flag to "true" will enable the use of concise resolver syntax + enable-concise-resolver-syntax: "false" diff --git a/docs/how-to-write-a-resolver.md b/docs/how-to-write-a-resolver.md index 772f1e0157f..da8a27036af 100644 --- a/docs/how-to-write-a-resolver.md +++ b/docs/how-to-write-a-resolver.md @@ -255,6 +255,7 @@ import ( The `Validate` method checks that the resolution-spec submitted as part of a resolution request are valid. Our example resolver doesn't expect any params in the spec so we'll simply ensure that the there are no params. +Our example resolver also expects format for the `url` to be `demoscheme://` so we'll validate this format. In the previous version, this was instead called `ValidateParams` method. See below for the differences. @@ -268,8 +269,24 @@ func (r *resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestS if len(req.Params) > 0 { return errors.New("no params allowed") } + url := req.URL + u, err := neturl.ParseRequestURI(url) + if err != nil { + return err + } + if u.Scheme != "demoscheme" { + return fmt.Errorf("Invalid Scheme. Want %s, Got %s", "demoscheme", u.Scheme) + } + if u.Path == "" { + return errors.New("Empty path.") + } return nil } +``` + +You'll also need to add the `net/url` as `neturl` and `"errors"` package to your list of imports at +the top of the file. + ``` {{% /tab %}} @@ -295,8 +312,8 @@ the top of the file. ## The `Resolve` method We implement the `Resolve` method to do the heavy lifting of fetching -the contents of a file and returning them. For this example we're just -going to return a hard-coded string of YAML. Since Tekton Pipelines +the contents of a file and returning them. It takes in the resolution request spec as input. +For this example we're just going to return a hard-coded string of YAML. Since Tekton Pipelines currently only supports fetching Pipeline resources via remote resolution that's what we'll return. @@ -465,6 +482,7 @@ func (*myResolvedResource) RefSource() *pipelinev1.RefSource { } ``` + ## The deployment configuration Finally, our resolver needs some deployment configuration so that it can diff --git a/docs/pipeline-api.md b/docs/pipeline-api.md index ca3c9dd0b31..d635d006cd6 100644 --- a/docs/pipeline-api.md +++ b/docs/pipeline-api.md @@ -304,6 +304,22 @@ resource being requested. For example: repo URL, commit SHA, path to file, the kind of authentication to leverage, etc.

    + + +url
    + +string + + + +(Optional) +

    URL is the runtime url passed to the resolver +to help it figure out how to resolver the resource being +requested. +This is currently at an ALPHA stability level and subject to +alpha API compatibility policies.

    + + @@ -358,6 +374,22 @@ resource being requested. For example: repo URL, commit SHA, path to file, the kind of authentication to leverage, etc.

    + + +url
    + +string + + + +(Optional) +

    URL is the runtime url passed to the resolver +to help it figure out how to resolver the resource being +requested. +This is currently at an ALPHA stability level and subject to +alpha API compatibility policies.

    + +

    ResolutionRequestStatus diff --git a/docs/resolver-template/cmd/resolver/main.go b/docs/resolver-template/cmd/resolver/main.go index 8bbb01f958c..1484b62a0d7 100644 --- a/docs/resolver-template/cmd/resolver/main.go +++ b/docs/resolver-template/cmd/resolver/main.go @@ -16,6 +16,8 @@ package main import ( "context" "errors" + "fmt" + neturl "net/url" pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" @@ -57,6 +59,13 @@ func (r *resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestS if len(req.Params) > 0 { return errors.New("no params allowed") } + u, err := neturl.ParseRequestURI(req.URL) + if err != nil { + return err + } + if u.Scheme != "demoscheme" { + return fmt.Errorf("Invalid Scheme. Want %s, Got %s", "demoscheme", u.Scheme) + } return nil } diff --git a/docs/resolver-template/cmd/resolver/main_test.go b/docs/resolver-template/cmd/resolver/main_test.go index 23b9dcf610b..46c6eedb160 100644 --- a/docs/resolver-template/cmd/resolver/main_test.go +++ b/docs/resolver-template/cmd/resolver/main_test.go @@ -18,15 +18,18 @@ package main import ( "encoding/base64" + "errors" "testing" "time" + pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" frtesting "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework/testing" resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" "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 +51,9 @@ func TestResolver(t *testing.T) { resolutioncommon.LabelKeyResolverType: "demo", }, }, - Spec: v1beta1.ResolutionRequestSpec{}, + Spec: v1beta1.ResolutionRequestSpec{ + URL: "demoscheme://foo/bar", + }, } d := test.Data{ ResolutionRequests: []*v1beta1.ResolutionRequest{request}, @@ -65,3 +70,138 @@ func TestResolver(t *testing.T) { frtesting.RunResolverReconcileTest(ctx, t, d, r, request, expectedStatus, expectedErr) } + +func TestResolver_Failure_Wrong_Scheme(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{ + URL: "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) +} + +func TestResolver_Failure_InvalidUrl(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{ + URL: "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": parse "foo/bar": invalid URI for request`, + }, + }, + }, + } + + // 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": parse "foo/bar": invalid URI for request`) + frtesting.RunResolverReconcileTest(ctx, t, d, r, request, expectedStatus, expectedErr) +} + +func TestResolver_Failure_InvalidParams(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{ + Params: []pipelinev1.Param{{ + Name: "foo", + Value: *pipelinev1.NewStructuredValues("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": no params allowed`, + }, + }, + }, + } + + // 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": no params allowed`) + frtesting.RunResolverReconcileTest(ctx, t, d, r, request, expectedStatus, expectedErr) +} diff --git a/pkg/apis/config/feature_flags.go b/pkg/apis/config/feature_flags.go index 326a33aebcf..d9c65cc21ae 100644 --- a/pkg/apis/config/feature_flags.go +++ b/pkg/apis/config/feature_flags.go @@ -102,12 +102,12 @@ const ( EnableCELInWhenExpression = "enable-cel-in-whenexpression" // EnableStepActions is the flag to enable the use of StepActions in Steps EnableStepActions = "enable-step-actions" - // EnableArtifacts is the flag to enable the use of Artifacts in Steps EnableArtifacts = "enable-artifacts" - // EnableParamEnum is the flag to enabled enum in params EnableParamEnum = "enable-param-enum" + // EnableConciseResolverSyntax is the flag to enable concise resolver syntax + EnableConciseResolverSyntax = "enable-concise-resolver-syntax" // DisableInlineSpec is the flag to disable embedded spec // in Taskrun or Pipelinerun @@ -168,6 +168,13 @@ var ( Stability: AlphaAPIFields, Enabled: DefaultAlphaFeatureEnabled, } + + // DefaultEnableConciseResolverSyntax is the default PerFeatureFlag value for EnableConciseResolverSyntax + DefaultEnableConciseResolverSyntax = PerFeatureFlag{ + Name: EnableConciseResolverSyntax, + Stability: AlphaAPIFields, + Enabled: DefaultAlphaFeatureEnabled, + } ) // FeatureFlags holds the features configurations @@ -189,17 +196,18 @@ type FeatureFlags struct { // ignore: skip trusted resources verification when no matching verification policies found // warn: skip trusted resources verification when no matching verification policies found and log a warning // fail: fail the taskrun or pipelines run if no matching verification policies found - VerificationNoMatchPolicy string - EnableProvenanceInStatus bool - ResultExtractionMethod string - MaxResultSize int - SetSecurityContext bool - Coschedule string - EnableCELInWhenExpression bool - EnableStepActions bool - EnableParamEnum bool - EnableArtifacts bool - DisableInlineSpec string + VerificationNoMatchPolicy string + EnableProvenanceInStatus bool + ResultExtractionMethod string + MaxResultSize int + SetSecurityContext bool + Coschedule string + EnableCELInWhenExpression bool + EnableStepActions bool + EnableParamEnum bool + EnableArtifacts bool + DisableInlineSpec string + EnableConciseResolverSyntax bool } // GetFeatureFlagsConfigName returns the name of the configmap containing all @@ -294,14 +302,15 @@ func NewFeatureFlagsFromMap(cfgMap map[string]string) (*FeatureFlags, error) { if err := setPerFeatureFlag(EnableParamEnum, DefaultEnableParamEnum, &tc.EnableParamEnum); err != nil { return nil, err } - if err := setPerFeatureFlag(EnableArtifacts, DefaultEnableArtifacts, &tc.EnableArtifacts); err != nil { return nil, err } if err := setFeatureInlineSpec(cfgMap, DisableInlineSpec, DefaultDisableInlineSpec, &tc.DisableInlineSpec); err != nil { return nil, err } - + if err := setPerFeatureFlag(EnableConciseResolverSyntax, DefaultEnableConciseResolverSyntax, &tc.EnableConciseResolverSyntax); err != nil { + return nil, err + } // Given that they are alpha features, Tekton Bundles and Custom Tasks should be switched on if // enable-api-fields is "alpha". If enable-api-fields is not "alpha" then fall back to the value of // each feature's individual flag. diff --git a/pkg/apis/config/feature_flags_test.go b/pkg/apis/config/feature_flags_test.go index cded62e7d44..08d33e12caa 100644 --- a/pkg/apis/config/feature_flags_test.go +++ b/pkg/apis/config/feature_flags_test.go @@ -58,6 +58,7 @@ func TestNewFeatureFlagsFromConfigMap(t *testing.T) { EnableStepActions: config.DefaultEnableStepActions.Enabled, EnableParamEnum: config.DefaultEnableParamEnum.Enabled, DisableInlineSpec: config.DefaultDisableInlineSpec, + EnableConciseResolverSyntax: config.DefaultEnableConciseResolverSyntax.Enabled, }, fileName: config.GetFeatureFlagsConfigName(), }, @@ -83,6 +84,7 @@ func TestNewFeatureFlagsFromConfigMap(t *testing.T) { EnableArtifacts: true, EnableParamEnum: true, DisableInlineSpec: "pipeline,pipelinerun,taskrun", + EnableConciseResolverSyntax: true, }, fileName: "feature-flags-all-flags-set", }, @@ -316,6 +318,9 @@ func TestNewFeatureFlagsConfigMapErrors(t *testing.T) { }, { fileName: "feature-flags-invalid-enable-artifacts", want: `failed parsing feature flags config "invalid": strconv.ParseBool: parsing "invalid": invalid syntax for feature enable-artifacts`, + }, { + fileName: "feature-flags-invalid-enable-concise-resolver-syntax", + want: `failed parsing feature flags config "invalid": strconv.ParseBool: parsing "invalid": invalid syntax for feature enable-concise-resolver-syntax`, }} { t.Run(tc.fileName, func(t *testing.T) { cm := test.ConfigMapFromTestFile(t, tc.fileName) diff --git a/pkg/apis/config/testdata/feature-flags-all-flags-set.yaml b/pkg/apis/config/testdata/feature-flags-all-flags-set.yaml index 6b539bc16da..3a798646664 100644 --- a/pkg/apis/config/testdata/feature-flags-all-flags-set.yaml +++ b/pkg/apis/config/testdata/feature-flags-all-flags-set.yaml @@ -37,3 +37,4 @@ data: enable-param-enum: "true" enable-artifacts: "true" disable-inline-spec: "pipeline,pipelinerun,taskrun" + enable-concise-resolver-syntax: "true" diff --git a/pkg/apis/config/testdata/feature-flags-invalid-enable-concise-resolver-syntax.yaml b/pkg/apis/config/testdata/feature-flags-invalid-enable-concise-resolver-syntax.yaml new file mode 100644 index 00000000000..4945e2f6f76 --- /dev/null +++ b/pkg/apis/config/testdata/feature-flags-invalid-enable-concise-resolver-syntax.yaml @@ -0,0 +1,21 @@ +# Copyright 2024 The Tekton Authors +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# https://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. + +apiVersion: v1 +kind: ConfigMap +metadata: + name: feature-flags + namespace: tekton-pipelines +data: + enable-concise-resolver-syntax: "invalid" diff --git a/pkg/apis/pipeline/v1/container_validation.go b/pkg/apis/pipeline/v1/container_validation.go index bfee6884b0b..a145da01d9a 100644 --- a/pkg/apis/pipeline/v1/container_validation.go +++ b/pkg/apis/pipeline/v1/container_validation.go @@ -18,45 +18,79 @@ package v1 import ( "context" + "fmt" "strings" + "net/url" + "github.com/tektoncd/pipeline/pkg/apis/config" "k8s.io/apimachinery/pkg/util/validation" "knative.dev/pkg/apis" ) -// Validate ensures that a supplied Ref field is populated -// correctly. No errors are returned for a nil Ref. -func (ref *Ref) Validate(ctx context.Context) (errs *apis.FieldError) { - if ref == nil { - return errs - } - +func validateRef(ctx context.Context, refName string, refResolver ResolverName, refParams Params) (errs *apis.FieldError) { switch { - case ref.Resolver != "" || ref.Params != nil: - if ref.Resolver != "" { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver", config.BetaAPIFields).ViaField("resolver")) - if ref.Name != "" { - errs = errs.Also(apis.ErrMultipleOneOf("name", "resolver")) - } - } - if ref.Params != nil { + case refResolver != "" || refParams != nil: + if refParams != nil { errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver params", config.BetaAPIFields).ViaField("params")) - if ref.Name != "" { + if refName != "" { errs = errs.Also(apis.ErrMultipleOneOf("name", "params")) } - if ref.Resolver == "" { + if refResolver == "" { errs = errs.Also(apis.ErrMissingField("resolver")) } - errs = errs.Also(ValidateParameters(ctx, ref.Params)) + errs = errs.Also(ValidateParameters(ctx, refParams)) + } + if refResolver != "" { + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver", config.BetaAPIFields).ViaField("resolver")) + if refName != "" { + // make sure that the name is url-like. + err := RefNameLikeUrl(refName) + if err == nil && !config.FromContextOrDefaults(ctx).FeatureFlags.EnableConciseResolverSyntax { + // If name is url-like then concise resolver syntax must be enabled + errs = errs.Also(apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use concise resolver syntax", config.EnableConciseResolverSyntax), "")) + } + if err != nil { + errs = errs.Also(apis.ErrInvalidValue(err, "name")) + } + } } - case ref.Name != "": - // ref name must be a valid k8s name - if errSlice := validation.IsQualifiedName(ref.Name); len(errSlice) != 0 { - errs = errs.Also(apis.ErrInvalidValue(strings.Join(errSlice, ","), "name")) + case refName != "": + // ref name can be a Url-like format. + if err := RefNameLikeUrl(refName); err == nil { + // If name is url-like then concise resolver syntax must be enabled + if !config.FromContextOrDefaults(ctx).FeatureFlags.EnableConciseResolverSyntax { + errs = errs.Also(apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use concise resolver syntax", config.EnableConciseResolverSyntax), "")) + } + // In stage1 of concise remote resolvers syntax, this is a required field. + // TODO: remove this check when implementing stage 2 where this is optional. + if refResolver == "" { + errs = errs.Also(apis.ErrMissingField("resolver")) + } + // Or, it must be a valid k8s name + } else { + // ref name must be a valid k8s name + if errSlice := validation.IsQualifiedName(refName); len(errSlice) != 0 { + errs = errs.Also(apis.ErrInvalidValue(strings.Join(errSlice, ","), "name")) + } } default: errs = errs.Also(apis.ErrMissingField("name")) } return errs } + +// Validate ensures that a supplied Ref field is populated +// correctly. No errors are returned for a nil Ref. +func (ref *Ref) Validate(ctx context.Context) (errs *apis.FieldError) { + if ref == nil { + return errs + } + return validateRef(ctx, ref.Name, ref.Resolver, ref.Params) +} + +// RefNameLikeUrl checks if the name is url parsable and returns an error if it isn't. +func RefNameLikeUrl(name string) error { + _, err := url.ParseRequestURI(name) + return err +} diff --git a/pkg/apis/pipeline/v1/container_validation_test.go b/pkg/apis/pipeline/v1/container_validation_test.go index 60c95f88120..7bdd0e36bfa 100644 --- a/pkg/apis/pipeline/v1/container_validation_test.go +++ b/pkg/apis/pipeline/v1/container_validation_test.go @@ -21,12 +21,22 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/tektoncd/pipeline/pkg/apis/config" cfgtesting "github.com/tektoncd/pipeline/pkg/apis/config/testing" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" "github.com/tektoncd/pipeline/test/diff" "knative.dev/pkg/apis" ) +func enableConciseResolverSyntax(ctx context.Context) context.Context { + return config.ToContext(ctx, &config.Config{ + FeatureFlags: &config.FeatureFlags{ + EnableConciseResolverSyntax: true, + EnableAPIFields: config.BetaAPIFields, + }, + }) +} + func TestRef_Valid(t *testing.T) { tests := []struct { name string @@ -93,29 +103,45 @@ func TestRef_Invalid(t *testing.T) { }, wantErr: apis.ErrMissingField("resolver"), }, { - name: "ref resolver disallowed in conjunction with ref name", + name: "ref with resolver and k8s style name", ref: &v1.Ref{ Name: "foo", ResolverRef: v1.ResolverRef{ Resolver: "git", }, }, - wantErr: apis.ErrMultipleOneOf("name", "resolver"), + wantErr: apis.ErrInvalidValue(`parse "foo": invalid URI for request`, "name"), + wc: enableConciseResolverSyntax, + }, { + name: "ref with url-like name without resolver", + ref: &v1.Ref{ + Name: "https://foo.com/bar", + }, + wantErr: apis.ErrMissingField("resolver"), + wc: enableConciseResolverSyntax, }, { - name: "ref params disallowed in conjunction with ref name", + name: "ref params disallowed in conjunction with pipelineref name", ref: &v1.Ref{ - Name: "bar", + Name: "https://foo/bar", ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "foo", - Value: v1.ParamValue{ - Type: v1.ParamTypeString, - StringVal: "bar", - }, - }}, + Resolver: "git", + Params: v1.Params{{Name: "foo", Value: v1.ParamValue{StringVal: "bar"}}}, }, }, - wantErr: apis.ErrMultipleOneOf("name", "params").Also(apis.ErrMissingField("resolver")), + wantErr: apis.ErrMultipleOneOf("name", "params"), + wc: enableConciseResolverSyntax, + }, { + name: "ref with url-like name without enable-concise-resolver-syntax", + ref: &v1.Ref{Name: "https://foo.com/bar"}, + wantErr: apis.ErrMissingField("resolver").Also(&apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + }), + }, { + name: "ref without enable-concise-resolver-syntax", + ref: &v1.Ref{Name: "https://foo.com/bar", ResolverRef: v1.ResolverRef{Resolver: "git"}}, + wantErr: &apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + }, }, { name: "invalid ref name", ref: &v1.Ref{Name: "_foo"}, diff --git a/pkg/apis/pipeline/v1/pipeline_types_test.go b/pkg/apis/pipeline/v1/pipeline_types_test.go index 61771b90f2a..12eb23477de 100644 --- a/pkg/apis/pipeline/v1/pipeline_types_test.go +++ b/pkg/apis/pipeline/v1/pipeline_types_test.go @@ -581,6 +581,7 @@ func TestPipelineTask_ValidateRegularTask_Failure(t *testing.T) { name string task PipelineTask expectedError apis.FieldError + configMap map[string]string }{{ name: "pipeline task - invalid taskSpec", task: PipelineTask{ @@ -612,15 +613,58 @@ func TestPipelineTask_ValidateRegularTask_Failure(t *testing.T) { Paths: []string{"taskRef.name"}, }, }, { - name: "pipeline task - taskRef with resolver and name", + name: "pipeline task - taskRef with resolver and k8s style name", task: PipelineTask{ Name: "foo", TaskRef: &TaskRef{Name: "foo", ResolverRef: ResolverRef{Resolver: "git"}}, }, + expectedError: apis.FieldError{ + Message: `invalid value: parse "foo": invalid URI for request`, + Paths: []string{"taskRef.name"}, + }, + configMap: map[string]string{"enable-concise-resolver-syntax": "true"}, + }, { + name: "pipeline task - taskRef with url-like name without enable-concise-resolver-syntax", + task: PipelineTask{ + Name: "foo", + TaskRef: &TaskRef{Name: "https://foo.com/bar"}, + }, + expectedError: *apis.ErrMissingField("taskRef.resolver").Also(&apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + Paths: []string{"taskRef"}, + }), + }, { + name: "pipeline task - taskRef without enable-concise-resolver-syntax", + task: PipelineTask{ + Name: "foo", + TaskRef: &TaskRef{Name: "https://foo.com/bar", ResolverRef: ResolverRef{Resolver: "git"}}, + }, + expectedError: apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + Paths: []string{"taskRef"}, + }, + }, { + name: "pipeline task - taskRef with url-like name without resolver", + task: PipelineTask{ + Name: "foo", + TaskRef: &TaskRef{Name: "https://foo.com/bar"}, + }, + expectedError: apis.FieldError{ + Message: `missing field(s)`, + Paths: []string{"taskRef.resolver"}, + }, + configMap: map[string]string{"enable-concise-resolver-syntax": "true"}, + }, { + name: "pipeline task - taskRef with name and params", + task: PipelineTask{ + Name: "foo", + TaskRef: &TaskRef{Name: "https://foo/bar", ResolverRef: ResolverRef{Resolver: "git", Params: Params{{Name: "foo", Value: ParamValue{StringVal: "bar"}}}}}, + }, expectedError: apis.FieldError{ Message: `expected exactly one, got both`, - Paths: []string{"taskRef.name", "taskRef.resolver"}, + Paths: []string{"taskRef.name", "taskRef.params"}, }, + configMap: map[string]string{"enable-concise-resolver-syntax": "true"}, }, { name: "pipeline task - taskRef with resolver params but no resolver", task: PipelineTask{ @@ -634,7 +678,8 @@ func TestPipelineTask_ValidateRegularTask_Failure(t *testing.T) { }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := tt.task.validateTask(context.Background()) + ctx := cfgtesting.SetFeatureFlags(context.Background(), t, tt.configMap) + err := tt.task.validateTask(ctx) if err == nil { t.Error("PipelineTask.validateTask() did not return error for invalid pipeline task") } diff --git a/pkg/apis/pipeline/v1/pipelineref_validation.go b/pkg/apis/pipeline/v1/pipelineref_validation.go index 9fa7c9894d0..c23db32a50a 100644 --- a/pkg/apis/pipeline/v1/pipelineref_validation.go +++ b/pkg/apis/pipeline/v1/pipelineref_validation.go @@ -19,7 +19,6 @@ package v1 import ( "context" - "github.com/tektoncd/pipeline/pkg/apis/config" "knative.dev/pkg/apis" ) @@ -27,28 +26,7 @@ import ( // correctly. No errors are returned for a nil PipelineRef. func (ref *PipelineRef) Validate(ctx context.Context) (errs *apis.FieldError) { if ref == nil { - return + return errs } - - if ref.Resolver != "" || ref.Params != nil { - if ref.Resolver != "" { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver", config.BetaAPIFields).ViaField("resolver")) - if ref.Name != "" { - errs = errs.Also(apis.ErrMultipleOneOf("name", "resolver")) - } - } - if ref.Params != nil { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver params", config.BetaAPIFields).ViaField("params")) - if ref.Name != "" { - errs = errs.Also(apis.ErrMultipleOneOf("name", "params")) - } - if ref.Resolver == "" { - errs = errs.Also(apis.ErrMissingField("resolver")) - } - errs = errs.Also(ValidateParameters(ctx, ref.Params)) - } - } else if ref.Name == "" { - errs = errs.Also(apis.ErrMissingField("name")) - } - return + return validateRef(ctx, ref.Name, ref.Resolver, ref.Params) } diff --git a/pkg/apis/pipeline/v1/pipelineref_validation_test.go b/pkg/apis/pipeline/v1/pipelineref_validation_test.go index 114eb6a0f10..62baa5df3ff 100644 --- a/pkg/apis/pipeline/v1/pipelineref_validation_test.go +++ b/pkg/apis/pipeline/v1/pipelineref_validation_test.go @@ -37,6 +37,13 @@ func TestPipelineRef_Invalid(t *testing.T) { name: "pipelineRef without Pipeline Name", ref: &v1.PipelineRef{}, wantErr: apis.ErrMissingField("name"), + }, { + name: "invalid pipelineref name", + ref: &v1.PipelineRef{Name: "_foo"}, + wantErr: &apis.FieldError{ + Message: `invalid value: name part must consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')`, + Paths: []string{"name"}, + }, }, { name: "pipelineref resolver disallowed without beta feature gate", ref: &v1.PipelineRef{ @@ -65,31 +72,45 @@ func TestPipelineRef_Invalid(t *testing.T) { wantErr: apis.ErrMissingField("resolver"), withContext: cfgtesting.EnableBetaAPIFields, }, { - name: "pipelineref resolver disallowed in conjunction with pipelineref name", + name: "pipelineRef with resolver and k8s style name", ref: &v1.PipelineRef{ Name: "foo", ResolverRef: v1.ResolverRef{ - Resolver: "bar", + Resolver: "git", }, }, - wantErr: apis.ErrMultipleOneOf("name", "resolver"), - withContext: cfgtesting.EnableBetaAPIFields, + wantErr: apis.ErrInvalidValue(`parse "foo": invalid URI for request`, "name"), + withContext: enableConciseResolverSyntax, }, { - name: "pipelineref params disallowed in conjunction with pipelineref name", + name: "pipelineRef with url-like name without resolver", ref: &v1.PipelineRef{ - Name: "bar", + Name: "https://foo.com/bar", + }, + wantErr: apis.ErrMissingField("resolver"), + withContext: enableConciseResolverSyntax, + }, { + name: "pipelineRef params disallowed in conjunction with pipelineref name", + ref: &v1.PipelineRef{ + Name: "https://foo/bar", ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "foo", - Value: v1.ParamValue{ - Type: v1.ParamTypeString, - StringVal: "bar", - }, - }}, + Resolver: "git", + Params: v1.Params{{Name: "foo", Value: v1.ParamValue{StringVal: "bar"}}}, }, }, - wantErr: apis.ErrMultipleOneOf("name", "params").Also(apis.ErrMissingField("resolver")), - withContext: cfgtesting.EnableBetaAPIFields, + wantErr: apis.ErrMultipleOneOf("name", "params"), + withContext: enableConciseResolverSyntax, + }, { + name: "pipelineRef with url-like name without enable-concise-resolver-syntax", + ref: &v1.PipelineRef{Name: "https://foo.com/bar"}, + wantErr: apis.ErrMissingField("resolver").Also(&apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + }), + }, { + name: "pipelineRef without enable-concise-resolver-syntax", + ref: &v1.PipelineRef{Name: "https://foo.com/bar", ResolverRef: v1.ResolverRef{Resolver: "git"}}, + wantErr: &apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + }, }} for _, tc := range tests { diff --git a/pkg/apis/pipeline/v1/taskref_validation.go b/pkg/apis/pipeline/v1/taskref_validation.go index 4f4e0330350..bbc5fbbfc48 100644 --- a/pkg/apis/pipeline/v1/taskref_validation.go +++ b/pkg/apis/pipeline/v1/taskref_validation.go @@ -18,10 +18,7 @@ package v1 import ( "context" - "strings" - "github.com/tektoncd/pipeline/pkg/apis/config" - "k8s.io/apimachinery/pkg/util/validation" "knative.dev/pkg/apis" ) @@ -31,32 +28,5 @@ func (ref *TaskRef) Validate(ctx context.Context) (errs *apis.FieldError) { if ref == nil { return errs } - - switch { - case ref.Resolver != "" || ref.Params != nil: - if ref.Resolver != "" { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver", config.BetaAPIFields).ViaField("resolver")) - if ref.Name != "" { - errs = errs.Also(apis.ErrMultipleOneOf("name", "resolver")) - } - } - if ref.Params != nil { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver params", config.BetaAPIFields).ViaField("params")) - if ref.Name != "" { - errs = errs.Also(apis.ErrMultipleOneOf("name", "params")) - } - if ref.Resolver == "" { - errs = errs.Also(apis.ErrMissingField("resolver")) - } - errs = errs.Also(ValidateParameters(ctx, ref.Params)) - } - case ref.Name != "": - // TaskRef name must be a valid k8s name - if errSlice := validation.IsQualifiedName(ref.Name); len(errSlice) != 0 { - errs = errs.Also(apis.ErrInvalidValue(strings.Join(errSlice, ","), "name")) - } - default: - errs = errs.Also(apis.ErrMissingField("name")) - } - return errs + return validateRef(ctx, ref.Name, ref.Resolver, ref.Params) } diff --git a/pkg/apis/pipeline/v1/taskref_validation_test.go b/pkg/apis/pipeline/v1/taskref_validation_test.go index d2c721bc6a1..8640045e566 100644 --- a/pkg/apis/pipeline/v1/taskref_validation_test.go +++ b/pkg/apis/pipeline/v1/taskref_validation_test.go @@ -120,31 +120,45 @@ func TestTaskRef_Invalid(t *testing.T) { wantErr: apis.ErrMissingField("resolver"), wc: cfgtesting.EnableBetaAPIFields, }, { - name: "taskref resolver disallowed in conjunction with taskref name", + name: "taskRef with resolver and k8s style name", taskRef: &v1.TaskRef{ Name: "foo", ResolverRef: v1.ResolverRef{ Resolver: "git", }, }, - wantErr: apis.ErrMultipleOneOf("name", "resolver"), - wc: cfgtesting.EnableBetaAPIFields, + wantErr: apis.ErrInvalidValue(`parse "foo": invalid URI for request`, "name"), + wc: enableConciseResolverSyntax, + }, { + name: "taskRef with url-like name without resolver", + taskRef: &v1.TaskRef{ + Name: "https://foo.com/bar", + }, + wantErr: apis.ErrMissingField("resolver"), + wc: enableConciseResolverSyntax, }, { - name: "taskref params disallowed in conjunction with taskref name", + name: "taskRef params disallowed in conjunction with pipelineref name", taskRef: &v1.TaskRef{ - Name: "bar", + Name: "https://foo/bar", ResolverRef: v1.ResolverRef{ - Params: v1.Params{{ - Name: "foo", - Value: v1.ParamValue{ - Type: v1.ParamTypeString, - StringVal: "bar", - }, - }}, + Resolver: "git", + Params: v1.Params{{Name: "foo", Value: v1.ParamValue{StringVal: "bar"}}}, }, }, - wantErr: apis.ErrMultipleOneOf("name", "params").Also(apis.ErrMissingField("resolver")), - wc: cfgtesting.EnableBetaAPIFields, + wantErr: apis.ErrMultipleOneOf("name", "params"), + wc: enableConciseResolverSyntax, + }, { + name: "taskRef with url-like name without enable-concise-resolver-syntax", + taskRef: &v1.TaskRef{Name: "https://foo.com/bar"}, + wantErr: apis.ErrMissingField("resolver").Also(&apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + }), + }, { + name: "taskRef without enable-concise-resolver-syntax", + taskRef: &v1.TaskRef{Name: "https://foo.com/bar", ResolverRef: v1.ResolverRef{Resolver: "git"}}, + wantErr: &apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + }, }} for _, ts := range tests { t.Run(ts.name, func(t *testing.T) { diff --git a/pkg/apis/pipeline/v1beta1/container_validation.go b/pkg/apis/pipeline/v1beta1/container_validation.go index bab6f8bc4d5..b9f66375d10 100644 --- a/pkg/apis/pipeline/v1beta1/container_validation.go +++ b/pkg/apis/pipeline/v1beta1/container_validation.go @@ -18,45 +18,79 @@ package v1beta1 import ( "context" + "fmt" "strings" + "net/url" + "github.com/tektoncd/pipeline/pkg/apis/config" "k8s.io/apimachinery/pkg/util/validation" "knative.dev/pkg/apis" ) -// Validate ensures that a supplied Ref field is populated -// correctly. No errors are returned for a nil Ref. -func (ref *Ref) Validate(ctx context.Context) (errs *apis.FieldError) { - if ref == nil { - return errs - } - +func validateRef(ctx context.Context, refName string, refResolver ResolverName, refParams Params) (errs *apis.FieldError) { switch { - case ref.Resolver != "" || ref.Params != nil: - if ref.Resolver != "" { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver", config.BetaAPIFields).ViaField("resolver")) - if ref.Name != "" { - errs = errs.Also(apis.ErrMultipleOneOf("name", "resolver")) - } - } - if ref.Params != nil { + case refResolver != "" || refParams != nil: + if refParams != nil { errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver params", config.BetaAPIFields).ViaField("params")) - if ref.Name != "" { + if refName != "" { errs = errs.Also(apis.ErrMultipleOneOf("name", "params")) } - if ref.Resolver == "" { + if refResolver == "" { errs = errs.Also(apis.ErrMissingField("resolver")) } - errs = errs.Also(ValidateParameters(ctx, ref.Params)) + errs = errs.Also(ValidateParameters(ctx, refParams)) + } + if refResolver != "" { + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver", config.BetaAPIFields).ViaField("resolver")) + if refName != "" { + // make sure that the name is url-like. + err := RefNameLikeUrl(refName) + if err == nil && !config.FromContextOrDefaults(ctx).FeatureFlags.EnableConciseResolverSyntax { + // If name is url-like then concise resolver syntax must be enabled + errs = errs.Also(apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use concise resolver syntax", config.EnableConciseResolverSyntax), "")) + } + if err != nil { + errs = errs.Also(apis.ErrInvalidValue(err, "name")) + } + } } - case ref.Name != "": - // Ref name must be a valid k8s name - if errSlice := validation.IsQualifiedName(ref.Name); len(errSlice) != 0 { - errs = errs.Also(apis.ErrInvalidValue(strings.Join(errSlice, ","), "name")) + case refName != "": + // ref name can be a Url-like format. + if err := RefNameLikeUrl(refName); err == nil { + // If name is url-like then concise resolver syntax must be enabled + if !config.FromContextOrDefaults(ctx).FeatureFlags.EnableConciseResolverSyntax { + errs = errs.Also(apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use concise resolver syntax", config.EnableConciseResolverSyntax), "")) + } + // In stage1 of concise remote resolvers syntax, this is a required field. + // TODO: remove this check when implementing stage 2 where this is optional. + if refResolver == "" { + errs = errs.Also(apis.ErrMissingField("resolver")) + } + // Or, it must be a valid k8s name + } else { + // ref name must be a valid k8s name + if errSlice := validation.IsQualifiedName(refName); len(errSlice) != 0 { + errs = errs.Also(apis.ErrInvalidValue(strings.Join(errSlice, ","), "name")) + } } default: errs = errs.Also(apis.ErrMissingField("name")) } return errs } + +// Validate ensures that a supplied Ref field is populated +// correctly. No errors are returned for a nil Ref. +func (ref *Ref) Validate(ctx context.Context) (errs *apis.FieldError) { + if ref == nil { + return errs + } + return validateRef(ctx, ref.Name, ref.Resolver, ref.Params) +} + +// RefNameLikeUrl checks if the name is url parsable and returns an error if it isn't. +func RefNameLikeUrl(name string) error { + _, err := url.ParseRequestURI(name) + return err +} diff --git a/pkg/apis/pipeline/v1beta1/container_validation_test.go b/pkg/apis/pipeline/v1beta1/container_validation_test.go index 95e7e4a28c0..79b23fa6f25 100644 --- a/pkg/apis/pipeline/v1beta1/container_validation_test.go +++ b/pkg/apis/pipeline/v1beta1/container_validation_test.go @@ -21,12 +21,22 @@ import ( "testing" "github.com/google/go-cmp/cmp" + "github.com/tektoncd/pipeline/pkg/apis/config" cfgtesting "github.com/tektoncd/pipeline/pkg/apis/config/testing" - "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" + v1beta1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" "github.com/tektoncd/pipeline/test/diff" "knative.dev/pkg/apis" ) +func enableConciseResolverSyntax(ctx context.Context) context.Context { + return config.ToContext(ctx, &config.Config{ + FeatureFlags: &config.FeatureFlags{ + EnableConciseResolverSyntax: true, + EnableAPIFields: config.BetaAPIFields, + }, + }) +} + func TestRef_Valid(t *testing.T) { tests := []struct { name string @@ -93,29 +103,45 @@ func TestRef_Invalid(t *testing.T) { }, wantErr: apis.ErrMissingField("resolver"), }, { - name: "ref resolver disallowed in conjunction with ref name", + name: "ref with resolver and k8s style name", ref: &v1beta1.Ref{ Name: "foo", ResolverRef: v1beta1.ResolverRef{ Resolver: "git", }, }, - wantErr: apis.ErrMultipleOneOf("name", "resolver"), + wantErr: apis.ErrInvalidValue(`parse "foo": invalid URI for request`, "name"), + wc: enableConciseResolverSyntax, + }, { + name: "ref with url-like name without resolver", + ref: &v1beta1.Ref{ + Name: "https://foo.com/bar", + }, + wantErr: apis.ErrMissingField("resolver"), + wc: enableConciseResolverSyntax, }, { - name: "ref params disallowed in conjunction with ref name", + name: "ref params disallowed in conjunction with pipelineref name", ref: &v1beta1.Ref{ - Name: "bar", + Name: "https://foo/bar", ResolverRef: v1beta1.ResolverRef{ - Params: v1beta1.Params{{ - Name: "foo", - Value: v1beta1.ParamValue{ - Type: v1beta1.ParamTypeString, - StringVal: "bar", - }, - }}, + Resolver: "git", + Params: v1beta1.Params{{Name: "foo", Value: v1beta1.ParamValue{StringVal: "bar"}}}, }, }, - wantErr: apis.ErrMultipleOneOf("name", "params").Also(apis.ErrMissingField("resolver")), + wantErr: apis.ErrMultipleOneOf("name", "params"), + wc: enableConciseResolverSyntax, + }, { + name: "ref with url-like name without enable-concise-resolver-syntax", + ref: &v1beta1.Ref{Name: "https://foo.com/bar"}, + wantErr: apis.ErrMissingField("resolver").Also(&apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + }), + }, { + name: "ref without enable-concise-resolver-syntax", + ref: &v1beta1.Ref{Name: "https://foo.com/bar", ResolverRef: v1beta1.ResolverRef{Resolver: "git"}}, + wantErr: &apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + }, }, { name: "invalid ref name", ref: &v1beta1.Ref{Name: "_foo"}, diff --git a/pkg/apis/pipeline/v1beta1/openapi_generated.go b/pkg/apis/pipeline/v1beta1/openapi_generated.go index a5199123b74..6a06a0867d2 100644 --- a/pkg/apis/pipeline/v1beta1/openapi_generated.go +++ b/pkg/apis/pipeline/v1beta1/openapi_generated.go @@ -6560,6 +6560,13 @@ func schema_pkg_apis_resolution_v1beta1_ResolutionRequestSpec(ref common.Referen }, }, }, + "url": { + SchemaProps: spec.SchemaProps{ + Description: "URL is the runtime url passed to the resolver to help it figure out how to resolver the resource being requested. This is currently at an ALPHA stability level and subject to alpha API compatibility policies.", + Type: []string{"string"}, + Format: "", + }, + }, }, }, }, diff --git a/pkg/apis/pipeline/v1beta1/pipeline_types_test.go b/pkg/apis/pipeline/v1beta1/pipeline_types_test.go index d0dc19b4cdf..28fdcf2382d 100644 --- a/pkg/apis/pipeline/v1beta1/pipeline_types_test.go +++ b/pkg/apis/pipeline/v1beta1/pipeline_types_test.go @@ -617,6 +617,7 @@ func TestPipelineTask_ValidateRegularTask_Failure(t *testing.T) { name string task PipelineTask expectedError apis.FieldError + configMap map[string]string }{{ name: "pipeline task - invalid taskSpec", task: PipelineTask{ @@ -655,15 +656,58 @@ func TestPipelineTask_ValidateRegularTask_Failure(t *testing.T) { }, expectedError: *apis.ErrGeneric("bundle requires \"enable-tekton-oci-bundles\" feature gate to be true but it is false"), }, { - name: "pipeline task - taskRef with resolver and name", + name: "pipeline task - taskRef with resolver and k8s style name", task: PipelineTask{ Name: "foo", TaskRef: &TaskRef{Name: "foo", ResolverRef: ResolverRef{Resolver: "git"}}, }, + expectedError: apis.FieldError{ + Message: `invalid value: parse "foo": invalid URI for request`, + Paths: []string{"taskRef.name"}, + }, + configMap: map[string]string{"enable-concise-resolver-syntax": "true"}, + }, { + name: "pipeline task - taskRef with url-like name without enable-concise-resolver-syntax", + task: PipelineTask{ + Name: "foo", + TaskRef: &TaskRef{Name: "https://foo.com/bar"}, + }, + expectedError: *apis.ErrMissingField("taskRef.resolver").Also(&apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + Paths: []string{"taskRef"}, + }), + }, { + name: "pipeline task - taskRef without enable-concise-resolver-syntax", + task: PipelineTask{ + Name: "foo", + TaskRef: &TaskRef{Name: "https://foo.com/bar", ResolverRef: ResolverRef{Resolver: "git"}}, + }, + expectedError: apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + Paths: []string{"taskRef"}, + }, + }, { + name: "pipeline task - taskRef with url-like name without resolver", + task: PipelineTask{ + Name: "foo", + TaskRef: &TaskRef{Name: "https://foo.com/bar"}, + }, + expectedError: apis.FieldError{ + Message: `missing field(s)`, + Paths: []string{"taskRef.resolver"}, + }, + configMap: map[string]string{"enable-concise-resolver-syntax": "true"}, + }, { + name: "pipeline task - taskRef with name and params", + task: PipelineTask{ + Name: "foo", + TaskRef: &TaskRef{Name: "https://foo/bar", ResolverRef: ResolverRef{Resolver: "git", Params: Params{{Name: "foo", Value: ParamValue{StringVal: "bar"}}}}}, + }, expectedError: apis.FieldError{ Message: `expected exactly one, got both`, - Paths: []string{"taskRef.name", "taskRef.resolver"}, + Paths: []string{"taskRef.name", "taskRef.params"}, }, + configMap: map[string]string{"enable-concise-resolver-syntax": "true"}, }, { name: "pipeline task - taskRef with resolver params but no resolver", task: PipelineTask{ @@ -677,7 +721,8 @@ func TestPipelineTask_ValidateRegularTask_Failure(t *testing.T) { }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { - err := tt.task.validateTask(context.Background()) + ctx := cfgtesting.SetFeatureFlags(context.Background(), t, tt.configMap) + err := tt.task.validateTask(ctx) if err == nil { t.Error("PipelineTask.validateTask() did not return error for invalid pipeline task") } diff --git a/pkg/apis/pipeline/v1beta1/pipelineref_validation.go b/pkg/apis/pipeline/v1beta1/pipelineref_validation.go index a0b7e02f18b..b5780112560 100644 --- a/pkg/apis/pipeline/v1beta1/pipelineref_validation.go +++ b/pkg/apis/pipeline/v1beta1/pipelineref_validation.go @@ -19,9 +19,11 @@ package v1beta1 import ( "context" "fmt" + "strings" "github.com/google/go-containerregistry/pkg/name" "github.com/tektoncd/pipeline/pkg/apis/config" + "k8s.io/apimachinery/pkg/util/validation" "knative.dev/pkg/apis" ) @@ -31,17 +33,8 @@ func (ref *PipelineRef) Validate(ctx context.Context) (errs *apis.FieldError) { if ref == nil { return errs } - - if ref.Resolver != "" || ref.Params != nil { - if ref.Resolver != "" { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver", config.BetaAPIFields).ViaField("resolver")) - if ref.Name != "" { - errs = errs.Also(apis.ErrMultipleOneOf("name", "resolver")) - } - if ref.Bundle != "" { - errs = errs.Also(apis.ErrMultipleOneOf("bundle", "resolver")) - } - } + switch { + case ref.Resolver != "" || ref.Params != nil: if ref.Params != nil { errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver params", config.BetaAPIFields).ViaField("params")) if ref.Name != "" { @@ -55,16 +48,52 @@ func (ref *PipelineRef) Validate(ctx context.Context) (errs *apis.FieldError) { } errs = errs.Also(ValidateParameters(ctx, ref.Params)) } - } else { + if ref.Resolver != "" { + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver", config.BetaAPIFields).ViaField("resolver")) + if ref.Name != "" { + // make sure that the name is url-like. + err := RefNameLikeUrl(ref.Name) + if err == nil && !config.FromContextOrDefaults(ctx).FeatureFlags.EnableConciseResolverSyntax { + // If name is url-like then concise resolver syntax must be enabled + errs = errs.Also(apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use concise resolver syntax", config.EnableConciseResolverSyntax), "")) + } + if err != nil { + errs = errs.Also(apis.ErrInvalidValue(err, "name")) + } + } + if ref.Bundle != "" { + errs = errs.Also(apis.ErrMultipleOneOf("bundle", "resolver")) + } + } + case ref.Bundle != "": if ref.Name == "" { errs = errs.Also(apis.ErrMissingField("name")) } - if ref.Bundle != "" { - errs = errs.Also(validateBundleFeatureFlag(ctx, "bundle", true).ViaField("bundle")) - if _, err := name.ParseReference(ref.Bundle); err != nil { - errs = errs.Also(apis.ErrInvalidValue("invalid bundle reference", "bundle", err.Error())) + errs = errs.Also(validateBundleFeatureFlag(ctx, "bundle", true).ViaField("bundle")) + if _, err := name.ParseReference(ref.Bundle); err != nil { + errs = errs.Also(apis.ErrInvalidValue("invalid bundle reference", "bundle", err.Error())) + } + case ref.Name != "": + // ref name can be a Url-like format. + if err := RefNameLikeUrl(ref.Name); err == nil { + // If name is url-like then concise resolver syntax must be enabled + if !config.FromContextOrDefaults(ctx).FeatureFlags.EnableConciseResolverSyntax { + errs = errs.Also(apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use concise resolver syntax", config.EnableConciseResolverSyntax), "")) + } + // In stage1 of concise remote resolvers syntax, this is a required field. + // TODO: remove this check when implementing stage 2 where this is optional. + if ref.Resolver == "" { + errs = errs.Also(apis.ErrMissingField("resolver")) + } + // Or, it must be a valid k8s name + } else { + // ref name must be a valid k8s name + if errSlice := validation.IsQualifiedName(ref.Name); len(errSlice) != 0 { + errs = errs.Also(apis.ErrInvalidValue(strings.Join(errSlice, ","), "name")) } } + default: + errs = errs.Also(apis.ErrMissingField("name")) } return //nolint:nakedret } diff --git a/pkg/apis/pipeline/v1beta1/pipelineref_validation_test.go b/pkg/apis/pipeline/v1beta1/pipelineref_validation_test.go index 82549d20ca9..a5a00617dc1 100644 --- a/pkg/apis/pipeline/v1beta1/pipelineref_validation_test.go +++ b/pkg/apis/pipeline/v1beta1/pipelineref_validation_test.go @@ -63,6 +63,13 @@ func TestPipelineRef_Invalid(t *testing.T) { name: "pipelineRef without Pipeline Name", ref: &v1beta1.PipelineRef{}, wantErr: apis.ErrMissingField("name"), + }, { + name: "invalid pipelineref name", + ref: &v1beta1.PipelineRef{Name: "_foo"}, + wantErr: &apis.FieldError{ + Message: `invalid value: name part must consist of alphanumeric characters, '-', '_' or '.', and must start and end with an alphanumeric character (e.g. 'MyName', or 'my.name', or '123-abc', regex used for validation is '([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9]')`, + Paths: []string{"name"}, + }, }, { name: "pipelineref resolver disallowed without beta feature gate", ref: &v1beta1.PipelineRef{ @@ -91,41 +98,45 @@ func TestPipelineRef_Invalid(t *testing.T) { wantErr: apis.ErrMissingField("resolver"), withContext: cfgtesting.EnableBetaAPIFields, }, { - name: "pipelineref resolver disallowed in conjunction with pipelineref name", + name: "pipelineRef with resolver and k8s style name", ref: &v1beta1.PipelineRef{ Name: "foo", ResolverRef: v1beta1.ResolverRef{ - Resolver: "bar", + Resolver: "git", }, }, - wantErr: apis.ErrMultipleOneOf("name", "resolver"), - withContext: cfgtesting.EnableBetaAPIFields, + wantErr: apis.ErrInvalidValue(`parse "foo": invalid URI for request`, "name"), + withContext: enableConciseResolverSyntax, }, { - name: "pipelineref resolver disallowed in conjunction with pipelineref bundle", + name: "pipelineRef with url-like name without resolver", ref: &v1beta1.PipelineRef{ - Bundle: "foo", - ResolverRef: v1beta1.ResolverRef{ - Resolver: "baz", - }, + Name: "https://foo.com/bar", }, - wantErr: apis.ErrMultipleOneOf("bundle", "resolver"), - withContext: enableTektonOCIBundles(t), + wantErr: apis.ErrMissingField("resolver"), + withContext: enableConciseResolverSyntax, }, { - name: "pipelineref params disallowed in conjunction with pipelineref name", + name: "pipelineRef params disallowed in conjunction with pipelineref name", ref: &v1beta1.PipelineRef{ - Name: "bar", + Name: "https://foo/bar", ResolverRef: v1beta1.ResolverRef{ - Params: v1beta1.Params{{ - Name: "foo", - Value: v1beta1.ParamValue{ - Type: v1beta1.ParamTypeString, - StringVal: "bar", - }, - }}, + Resolver: "git", + Params: []v1beta1.Param{{Name: "foo", Value: v1beta1.ParamValue{StringVal: "bar"}}}, }, }, - wantErr: apis.ErrMultipleOneOf("name", "params").Also(apis.ErrMissingField("resolver")), - withContext: cfgtesting.EnableBetaAPIFields, + wantErr: apis.ErrMultipleOneOf("name", "params"), + withContext: enableConciseResolverSyntax, + }, { + name: "pipelineRef with url-like name without enable-concise-resolver-syntax", + ref: &v1beta1.PipelineRef{Name: "https://foo.com/bar"}, + wantErr: apis.ErrMissingField("resolver").Also(&apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + }), + }, { + name: "pipelineRef without enable-concise-resolver-syntax", + ref: &v1beta1.PipelineRef{Name: "https://foo.com/bar", ResolverRef: v1beta1.ResolverRef{Resolver: "git"}}, + wantErr: &apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + }, }, { name: "pipelineref params disallowed in conjunction with pipelineref bundle", ref: &v1beta1.PipelineRef{ diff --git a/pkg/apis/pipeline/v1beta1/swagger.json b/pkg/apis/pipeline/v1beta1/swagger.json index 261b6878662..91cf8fe17fd 100644 --- a/pkg/apis/pipeline/v1beta1/swagger.json +++ b/pkg/apis/pipeline/v1beta1/swagger.json @@ -1722,6 +1722,10 @@ "$ref": "#/definitions/v1.Param" }, "x-kubernetes-list-type": "atomic" + }, + "url": { + "description": "URL is the runtime url passed to the resolver to help it figure out how to resolver the resource being requested. This is currently at an ALPHA stability level and subject to alpha API compatibility policies.", + "type": "string" } } }, diff --git a/pkg/apis/pipeline/v1beta1/taskref_validation.go b/pkg/apis/pipeline/v1beta1/taskref_validation.go index a3e2bb036c3..7db46c0d9c5 100644 --- a/pkg/apis/pipeline/v1beta1/taskref_validation.go +++ b/pkg/apis/pipeline/v1beta1/taskref_validation.go @@ -18,6 +18,7 @@ package v1beta1 import ( "context" + "fmt" "strings" "github.com/google/go-containerregistry/pkg/name" @@ -32,18 +33,8 @@ func (ref *TaskRef) Validate(ctx context.Context) (errs *apis.FieldError) { if ref == nil { return errs } - switch { case ref.Resolver != "" || ref.Params != nil: - if ref.Resolver != "" { - errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver", config.BetaAPIFields).ViaField("resolver")) - if ref.Name != "" { - errs = errs.Also(apis.ErrMultipleOneOf("name", "resolver")) - } - if ref.Bundle != "" { - errs = errs.Also(apis.ErrMultipleOneOf("bundle", "resolver")) - } - } if ref.Params != nil { errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver params", config.BetaAPIFields).ViaField("params")) if ref.Name != "" { @@ -57,6 +48,23 @@ func (ref *TaskRef) Validate(ctx context.Context) (errs *apis.FieldError) { } errs = errs.Also(ValidateParameters(ctx, ref.Params)) } + if ref.Resolver != "" { + errs = errs.Also(config.ValidateEnabledAPIFields(ctx, "resolver", config.BetaAPIFields).ViaField("resolver")) + if ref.Name != "" { + // make sure that the name is url-like. + err := RefNameLikeUrl(ref.Name) + if err == nil && !config.FromContextOrDefaults(ctx).FeatureFlags.EnableConciseResolverSyntax { + // If name is url-like then concise resolver syntax must be enabled + errs = errs.Also(apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use concise resolver syntax", config.EnableConciseResolverSyntax), "")) + } + if err != nil { + errs = errs.Also(apis.ErrInvalidValue(err, "name")) + } + } + if ref.Bundle != "" { + errs = errs.Also(apis.ErrMultipleOneOf("bundle", "resolver")) + } + } case ref.Bundle != "": if ref.Name == "" { errs = errs.Also(apis.ErrMissingField("name")) @@ -65,13 +73,27 @@ func (ref *TaskRef) Validate(ctx context.Context) (errs *apis.FieldError) { if _, err := name.ParseReference(ref.Bundle); err != nil { errs = errs.Also(apis.ErrInvalidValue("invalid bundle reference", "bundle", err.Error())) } - default: - if ref.Name == "" { - errs = errs.Also(apis.ErrMissingField("name")) - } else if errSlice := validation.IsQualifiedName(ref.Name); len(errSlice) != 0 { - // TaskRef name must be a valid k8s name - errs = errs.Also(apis.ErrInvalidValue(strings.Join(errSlice, ","), "name")) + case ref.Name != "": + // ref name can be a Url-like format. + if err := RefNameLikeUrl(ref.Name); err == nil { + // If name is url-like then concise resolver syntax must be enabled + if !config.FromContextOrDefaults(ctx).FeatureFlags.EnableConciseResolverSyntax { + errs = errs.Also(apis.ErrGeneric(fmt.Sprintf("feature flag %s should be set to true to use concise resolver syntax", config.EnableConciseResolverSyntax), "")) + } + // In stage1 of concise remote resolvers syntax, this is a required field. + // TODO: remove this check when implementing stage 2 where this is optional. + if ref.Resolver == "" { + errs = errs.Also(apis.ErrMissingField("resolver")) + } + // Or, it must be a valid k8s name + } else { + // ref name must be a valid k8s name + if errSlice := validation.IsQualifiedName(ref.Name); len(errSlice) != 0 { + errs = errs.Also(apis.ErrInvalidValue(strings.Join(errSlice, ","), "name")) + } } + default: + errs = errs.Also(apis.ErrMissingField("name")) } - return errs + return //nolint:nakedret } diff --git a/pkg/apis/pipeline/v1beta1/taskref_validation_test.go b/pkg/apis/pipeline/v1beta1/taskref_validation_test.go index 7d1f4f488ff..09136f812c3 100644 --- a/pkg/apis/pipeline/v1beta1/taskref_validation_test.go +++ b/pkg/apis/pipeline/v1beta1/taskref_validation_test.go @@ -113,22 +113,45 @@ func TestTaskRef_Invalid(t *testing.T) { wantErr: apis.ErrInvalidValue("invalid bundle reference", "bundle", "could not parse reference: invalid reference"), wc: enableTektonOCIBundles(t), }, { - name: "taskref params disallowed without resolver", + name: "taskRef with resolver and k8s style name", taskRef: &v1beta1.TaskRef{ + Name: "foo", ResolverRef: v1beta1.ResolverRef{ - Params: v1beta1.Params{}, + Resolver: "git", }, }, + wantErr: apis.ErrInvalidValue(`parse "foo": invalid URI for request`, "name"), + wc: enableConciseResolverSyntax, + }, { + name: "taskRef with url-like name without resolver", + taskRef: &v1beta1.TaskRef{ + Name: "https://foo.com/bar", + }, wantErr: apis.ErrMissingField("resolver"), + wc: enableConciseResolverSyntax, }, { - name: "taskref resolver disallowed in conjunction with taskref name", + name: "taskRef params disallowed in conjunction with pipelineref name", taskRef: &v1beta1.TaskRef{ - Name: "foo", + Name: "https://foo/bar", ResolverRef: v1beta1.ResolverRef{ Resolver: "git", + Params: v1beta1.Params{{Name: "foo", Value: v1beta1.ParamValue{StringVal: "bar"}}}, }, }, - wantErr: apis.ErrMultipleOneOf("name", "resolver"), + wantErr: apis.ErrMultipleOneOf("name", "params"), + wc: enableConciseResolverSyntax, + }, { + name: "taskRef with url-like name without enable-concise-resolver-syntax", + taskRef: &v1beta1.TaskRef{Name: "https://foo.com/bar"}, + wantErr: apis.ErrMissingField("resolver").Also(&apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + }), + }, { + name: "taskRef without enable-concise-resolver-syntax", + taskRef: &v1beta1.TaskRef{Name: "https://foo.com/bar", ResolverRef: v1beta1.ResolverRef{Resolver: "git"}}, + wantErr: &apis.FieldError{ + Message: `feature flag enable-concise-resolver-syntax should be set to true to use concise resolver syntax`, + }, }, { name: "taskref resolver disallowed in conjunction with taskref bundle", taskRef: &v1beta1.TaskRef{ @@ -139,21 +162,6 @@ func TestTaskRef_Invalid(t *testing.T) { }, wantErr: apis.ErrMultipleOneOf("bundle", "resolver"), wc: enableTektonOCIBundles(t), - }, { - name: "taskref params disallowed in conjunction with taskref name", - taskRef: &v1beta1.TaskRef{ - Name: "bar", - ResolverRef: v1beta1.ResolverRef{ - Params: v1beta1.Params{{ - Name: "foo", - Value: v1beta1.ParamValue{ - Type: v1beta1.ParamTypeString, - StringVal: "bar", - }, - }}, - }, - }, - wantErr: apis.ErrMultipleOneOf("name", "params").Also(apis.ErrMissingField("resolver")), }, { name: "taskref params disallowed in conjunction with taskref bundle", taskRef: &v1beta1.TaskRef{ diff --git a/pkg/apis/resolution/v1beta1/resolution_request_types.go b/pkg/apis/resolution/v1beta1/resolution_request_types.go index 60b51fa0498..f78a4a493c3 100644 --- a/pkg/apis/resolution/v1beta1/resolution_request_types.go +++ b/pkg/apis/resolution/v1beta1/resolution_request_types.go @@ -64,6 +64,13 @@ type ResolutionRequestSpec struct { // +optional // +listType=atomic Params []pipelinev1.Param `json:"params,omitempty"` + // URL is the runtime url passed to the resolver + // to help it figure out how to resolver the resource being + // requested. + // This is currently at an ALPHA stability level and subject to + // alpha API compatibility policies. + // +optional + URL string `json:"url,omitempty"` } // ResolutionRequestStatus are all the fields in a ResolutionRequest's diff --git a/pkg/reconciler/pipelinerun/pipelinerun_test.go b/pkg/reconciler/pipelinerun/pipelinerun_test.go index b1f9904ccf3..ee053617c36 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun_test.go +++ b/pkg/reconciler/pipelinerun/pipelinerun_test.go @@ -16723,7 +16723,7 @@ spec: // the ResolutionRequest's name is generated by resolverName, namespace and runName. func getResolvedResolutionRequest(t *testing.T, resolverName string, resourceBytes []byte, namespace string, runName string) resolutionv1beta1.ResolutionRequest { t.Helper() - name, err := remoteresource.GenerateDeterministicName(resolverName, namespace+"/"+runName, nil) + name, err := remoteresource.GenerateDeterministicNameFromSpec(resolverName, namespace+"/"+runName, &resolutionv1beta1.ResolutionRequestSpec{}) if err != nil { t.Errorf("error generating name for %s/%s/%s: %v", resolverName, namespace, runName, err) } diff --git a/pkg/reconciler/pipelinerun/resources/apply.go b/pkg/reconciler/pipelinerun/resources/apply.go index 3aeb0accebd..b971d94d4f8 100644 --- a/pkg/reconciler/pipelinerun/resources/apply.go +++ b/pkg/reconciler/pipelinerun/resources/apply.go @@ -249,8 +249,11 @@ func ApplyTaskResults(targets PipelineRunState, resolvedResultRefs ResolvedResul } } pipelineTask.When = pipelineTask.When.ReplaceVariables(stringReplacements, arrayReplacements) - if pipelineTask.TaskRef != nil && pipelineTask.TaskRef.Params != nil { - pipelineTask.TaskRef.Params = pipelineTask.TaskRef.Params.ReplaceVariables(stringReplacements, arrayReplacements, objectReplacements) + if pipelineTask.TaskRef != nil { + if pipelineTask.TaskRef.Params != nil { + pipelineTask.TaskRef.Params = pipelineTask.TaskRef.Params.ReplaceVariables(stringReplacements, arrayReplacements, objectReplacements) + } + pipelineTask.TaskRef.Name = substitution.ApplyReplacements(pipelineTask.TaskRef.Name, stringReplacements) } pipelineTask.DisplayName = substitution.ApplyReplacements(pipelineTask.DisplayName, stringReplacements) for i, workspace := range pipelineTask.Workspaces { @@ -268,8 +271,11 @@ func ApplyPipelineTaskStateContext(state PipelineRunState, replacements map[stri pipelineTask := resolvedPipelineRunTask.PipelineTask.DeepCopy() pipelineTask.Params = pipelineTask.Params.ReplaceVariables(replacements, nil, nil) pipelineTask.When = pipelineTask.When.ReplaceVariables(replacements, nil) - if pipelineTask.TaskRef != nil && pipelineTask.TaskRef.Params != nil { - pipelineTask.TaskRef.Params = pipelineTask.TaskRef.Params.ReplaceVariables(replacements, nil, nil) + if pipelineTask.TaskRef != nil { + if pipelineTask.TaskRef.Params != nil { + pipelineTask.TaskRef.Params = pipelineTask.TaskRef.Params.ReplaceVariables(replacements, nil, nil) + } + pipelineTask.TaskRef.Name = substitution.ApplyReplacements(pipelineTask.TaskRef.Name, replacements) } pipelineTask.DisplayName = substitution.ApplyReplacements(pipelineTask.DisplayName, replacements) resolvedPipelineRunTask.PipelineTask = pipelineTask @@ -311,8 +317,11 @@ func ApplyReplacements(p *v1.PipelineSpec, replacements map[string]string, array p.Tasks[i].Workspaces[j].SubPath = substitution.ApplyReplacements(p.Tasks[i].Workspaces[j].SubPath, replacements) } p.Tasks[i].When = p.Tasks[i].When.ReplaceVariables(replacements, arrayReplacements) - if p.Tasks[i].TaskRef != nil && p.Tasks[i].TaskRef.Params != nil { - p.Tasks[i].TaskRef.Params = p.Tasks[i].TaskRef.Params.ReplaceVariables(replacements, arrayReplacements, objectReplacements) + if p.Tasks[i].TaskRef != nil { + if p.Tasks[i].TaskRef.Params != nil { + p.Tasks[i].TaskRef.Params = p.Tasks[i].TaskRef.Params.ReplaceVariables(replacements, arrayReplacements, objectReplacements) + } + p.Tasks[i].TaskRef.Name = substitution.ApplyReplacements(p.Tasks[i].TaskRef.Name, replacements) } p.Tasks[i] = propagateParams(p.Tasks[i], replacements, arrayReplacements, objectReplacements) } @@ -331,8 +340,11 @@ func ApplyReplacements(p *v1.PipelineSpec, replacements map[string]string, array p.Finally[i].Workspaces[j].SubPath = substitution.ApplyReplacements(p.Finally[i].Workspaces[j].SubPath, replacements) } p.Finally[i].When = p.Finally[i].When.ReplaceVariables(replacements, arrayReplacements) - if p.Finally[i].TaskRef != nil && p.Finally[i].TaskRef.Params != nil { - p.Finally[i].TaskRef.Params = p.Finally[i].TaskRef.Params.ReplaceVariables(replacements, arrayReplacements, objectReplacements) + if p.Finally[i].TaskRef != nil { + if p.Finally[i].TaskRef.Params != nil { + p.Finally[i].TaskRef.Params = p.Finally[i].TaskRef.Params.ReplaceVariables(replacements, arrayReplacements, objectReplacements) + } + p.Finally[i].TaskRef.Name = substitution.ApplyReplacements(p.Finally[i].TaskRef.Name, replacements) } p.Finally[i] = propagateParams(p.Finally[i], replacements, arrayReplacements, objectReplacements) } diff --git a/pkg/reconciler/pipelinerun/resources/pipelineref.go b/pkg/reconciler/pipelinerun/resources/pipelineref.go index 226ca35c201..16844d895bd 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelineref.go +++ b/pkg/reconciler/pipelinerun/resources/pipelineref.go @@ -31,6 +31,7 @@ import ( "github.com/tektoncd/pipeline/pkg/remote" "github.com/tektoncd/pipeline/pkg/remoteresolution/remote/resolution" remoteresource "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" + "github.com/tektoncd/pipeline/pkg/substitution" "github.com/tektoncd/pipeline/pkg/trustedresources" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -70,10 +71,17 @@ func GetPipelineFunc(ctx context.Context, k8s kubernetes.Interface, tekton clien stringReplacements[k] = v } replacedParams := pr.Params.ReplaceVariables(stringReplacements, arrayReplacements, objectReplacements) - + var url string + // The name is url-like so its not a local reference. + if err := v1.RefNameLikeUrl(pr.Name); err == nil { + // apply variable replacements in the name. + pr.Name = substitution.ApplyReplacements(pr.Name, stringReplacements) + url = pr.Name + } resolverPayload := remoteresource.ResolverPayload{ ResolutionSpec: &resolutionV1beta1.ResolutionRequestSpec{ Params: replacedParams, + URL: url, }, } resolver := resolution.NewResolver(requester, pipelineRun, string(pr.Resolver), resolverPayload) diff --git a/pkg/reconciler/pipelinerun/resources/pipelineref_test.go b/pkg/reconciler/pipelinerun/resources/pipelineref_test.go index 1f94e784bd3..87d48306cf5 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelineref_test.go +++ b/pkg/reconciler/pipelinerun/resources/pipelineref_test.go @@ -438,6 +438,7 @@ func TestGetPipelineFunc_RemoteResolution_ReplacedParams(t *testing.T) { ctx = config.ToContext(ctx, cfg) pipeline := parse.MustParseV1PipelineAndSetDefaults(t, pipelineYAMLString) pipelineRef := &v1.PipelineRef{ + Name: "https://foo/bar", ResolverRef: v1.ResolverRef{ Resolver: "git", Params: []v1.Param{{ @@ -467,6 +468,7 @@ func TestGetPipelineFunc_RemoteResolution_ReplacedParams(t *testing.T) { Name: "bar", Value: *v1.NewStructuredValues("test-pipeline"), }}, + URL: "https://foo/bar", }, }, } diff --git a/pkg/reconciler/taskrun/resources/taskref.go b/pkg/reconciler/taskrun/resources/taskref.go index fa7e1200c05..03cea99ee25 100644 --- a/pkg/reconciler/taskrun/resources/taskref.go +++ b/pkg/reconciler/taskrun/resources/taskref.go @@ -31,6 +31,7 @@ import ( "github.com/tektoncd/pipeline/pkg/remote" "github.com/tektoncd/pipeline/pkg/remoteresolution/remote/resolution" remoteresource "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" + "github.com/tektoncd/pipeline/pkg/substitution" "github.com/tektoncd/pipeline/pkg/trustedresources" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/runtime" @@ -97,6 +98,7 @@ func GetTaskFunc(ctx context.Context, k8s kubernetes.Interface, tekton clientset // casting it to a TaskObject. return func(ctx context.Context, name string) (*v1.Task, *v1.RefSource, *trustedresources.VerificationResult, error) { var replacedParams v1.Params + var url string if ownerAsTR, ok := owner.(*v1.TaskRun); ok { stringReplacements, arrayReplacements, _ := replacementsFromParams(ownerAsTR.Spec.Params) for k, v := range getContextReplacements("", ownerAsTR) { @@ -106,6 +108,11 @@ func GetTaskFunc(ctx context.Context, k8s kubernetes.Interface, tekton clientset p.Value.ApplyReplacements(stringReplacements, arrayReplacements, nil) replacedParams = append(replacedParams, p) } + if err := v1.RefNameLikeUrl(tr.Name); err == nil { + // The name is url-like so its not a local reference. + tr.Name = substitution.ApplyReplacements(tr.Name, stringReplacements) + url = tr.Name + } } else { replacedParams = append(replacedParams, tr.Params...) } @@ -114,6 +121,7 @@ func GetTaskFunc(ctx context.Context, k8s kubernetes.Interface, tekton clientset Namespace: namespace, ResolutionSpec: &resolutionV1beta1.ResolutionRequestSpec{ Params: replacedParams, + URL: url, }, } resolver := resolution.NewResolver(requester, owner, string(tr.Resolver), resolverPayload) @@ -149,6 +157,7 @@ func GetStepActionFunc(tekton clientset.Interface, k8s kubernetes.Interface, req Namespace: namespace, ResolutionSpec: &resolutionV1beta1.ResolutionRequestSpec{ Params: step.Ref.Params, + URL: step.Ref.Name, }, } resolver := resolution.NewResolver(requester, tr, string(step.Ref.Resolver), resolverPayload) diff --git a/pkg/reconciler/taskrun/resources/taskref_test.go b/pkg/reconciler/taskrun/resources/taskref_test.go index 643c5754e66..9bc388fdb85 100644 --- a/pkg/reconciler/taskrun/resources/taskref_test.go +++ b/pkg/reconciler/taskrun/resources/taskref_test.go @@ -1202,6 +1202,7 @@ func TestGetTaskFunc_RemoteResolution_ReplacedParams(t *testing.T) { ctx = config.ToContext(ctx, cfg) task := parse.MustParseV1TaskAndSetDefaults(t, taskYAMLString) taskRef := &v1.TaskRef{ + Name: "https://foo/bar", ResolverRef: v1.ResolverRef{ Resolver: "git", Params: []v1.Param{{ @@ -1231,6 +1232,7 @@ func TestGetTaskFunc_RemoteResolution_ReplacedParams(t *testing.T) { Name: "bar", Value: *v1.NewStructuredValues("test-task"), }}, + URL: "https://foo/bar", }, }, } diff --git a/pkg/reconciler/taskrun/taskrun_test.go b/pkg/reconciler/taskrun/taskrun_test.go index 85a4848d22d..e945a7d1fe3 100644 --- a/pkg/reconciler/taskrun/taskrun_test.go +++ b/pkg/reconciler/taskrun/taskrun_test.go @@ -7039,7 +7039,7 @@ func TestIsConcurrentModificationError(t *testing.T) { // the ResolutionRequest's name is generated by resolverName, namespace and runName. func getResolvedResolutionRequest(t *testing.T, resolverName string, resourceBytes []byte, namespace string, runName string) resolutionv1beta1.ResolutionRequest { t.Helper() - name, err := remoteresource.GenerateDeterministicName(resolverName, namespace+"/"+runName, nil) + name, err := remoteresource.GenerateDeterministicNameFromSpec(resolverName, namespace+"/"+runName, &resolutionv1beta1.ResolutionRequestSpec{}) if err != nil { t.Errorf("error generating name for %s/%s/%s: %v", resolverName, namespace, runName, err) } diff --git a/pkg/remoteresolution/resolver/bundle/resolver.go b/pkg/remoteresolution/resolver/bundle/resolver.go index 85abd28672f..4f8612931a0 100644 --- a/pkg/remoteresolution/resolver/bundle/resolver.go +++ b/pkg/remoteresolution/resolver/bundle/resolver.go @@ -18,6 +18,7 @@ package bundle import ( "context" + "errors" "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" @@ -69,10 +70,18 @@ func (r *Resolver) GetSelector(context.Context) map[string]string { // Validate ensures reqolution request spec from a request are as expected. func (r *Resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestSpec) error { - return bundle.ValidateParams(ctx, req.Params) + if len(req.Params) > 0 { + return bundle.ValidateParams(ctx, req.Params) + } + // Remove this error once validate url has been implemented. + return errors.New("cannot validate request. the Validate method has not been implemented.") } -// Resolve uses the given params to resolve the requested file or resource. +// Resolve uses the given request spec resolve the requested file or resource. func (r *Resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (resolutionframework.ResolvedResource, error) { - return bundle.ResolveRequest(ctx, r.kubeClientSet, req) + if len(req.Params) > 0 { + return bundle.ResolveRequest(ctx, r.kubeClientSet, req) + } + // Remove this error once resolution of url has been implemented. + return nil, errors.New("the Resolve method has not been implemented.") } diff --git a/pkg/remoteresolution/resolver/cluster/resolver.go b/pkg/remoteresolution/resolver/cluster/resolver.go index 7c1e9072334..c08f8a18bd3 100644 --- a/pkg/remoteresolution/resolver/cluster/resolver.go +++ b/pkg/remoteresolution/resolver/cluster/resolver.go @@ -18,6 +18,7 @@ package cluster import ( "context" + "errors" "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" clientset "github.com/tektoncd/pipeline/pkg/client/clientset/versioned" @@ -70,13 +71,21 @@ func (r *Resolver) GetSelector(_ context.Context) map[string]string { // Validate returns an error if the given parameter map is not // valid for a resource request targeting the cluster resolver. func (r *Resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestSpec) error { - return cluster.ValidateParams(ctx, req.Params) + if len(req.Params) > 0 { + return cluster.ValidateParams(ctx, req.Params) + } + // Remove this error once validate url has been implemented. + return errors.New("cannot validate request. the Validate method has not been implemented.") } // Resolve performs the work of fetching a resource from a namespace with the given -// parameters. +// resolution spec. func (r *Resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (resolutionframework.ResolvedResource, error) { - return cluster.ResolveFromParams(ctx, req.Params, r.pipelineClientSet) + if len(req.Params) > 0 { + return cluster.ResolveFromParams(ctx, req.Params, r.pipelineClientSet) + } + // Remove this error once resolution of url has been implemented. + return nil, errors.New("the Resolve method has not been implemented.") } var _ resolutionframework.ConfigWatcher = &Resolver{} diff --git a/pkg/remoteresolution/resolver/framework/fakeresolver.go b/pkg/remoteresolution/resolver/framework/fakeresolver.go index 995ead2e19e..ad7da0e6b85 100644 --- a/pkg/remoteresolution/resolver/framework/fakeresolver.go +++ b/pkg/remoteresolution/resolver/framework/fakeresolver.go @@ -18,6 +18,7 @@ package framework import ( "context" + "fmt" "time" "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" @@ -25,6 +26,8 @@ import ( "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" ) +const FakeUrl string = "fake://url" + var _ Resolver = &FakeResolver{} // FakeResolver implements a framework.Resolver that can fetch pre-configured strings based on a parameter value, or return @@ -56,13 +59,26 @@ func (r *FakeResolver) GetSelector(_ context.Context) map[string]string { // Validate returns an error if the given parameter map is not // valid for a resource request targeting the fake resolver. func (r *FakeResolver) Validate(_ context.Context, req *v1beta1.ResolutionRequestSpec) error { - return framework.ValidateParams(req.Params) + if len(req.Params) > 0 { + return framework.ValidateParams(req.Params) + } + if req.URL != FakeUrl { + return fmt.Errorf("Wrong url. Expected: %s, Got: %s", FakeUrl, req.URL) + } + return nil } // Resolve performs the work of fetching a file from the fake resolver given a map of // parameters. func (r *FakeResolver) Resolve(_ context.Context, req *v1beta1.ResolutionRequestSpec) (framework.ResolvedResource, error) { - return framework.Resolve(req.Params, r.ForParam) + if len(req.Params) > 0 { + return framework.Resolve(req.Params, r.ForParam) + } + frr, ok := r.ForParam[req.URL] + if !ok { + return nil, fmt.Errorf("couldn't find resource for url %s", req.URL) + } + return frr, nil } var _ framework.TimedResolution = &FakeResolver{} diff --git a/pkg/remoteresolution/resolver/framework/reconciler_test.go b/pkg/remoteresolution/resolver/framework/reconciler_test.go index e72582ca471..6c11ecc8a0f 100644 --- a/pkg/remoteresolution/resolver/framework/reconciler_test.go +++ b/pkg/remoteresolution/resolver/framework/reconciler_test.go @@ -148,6 +148,142 @@ func TestReconcile(t *testing.T) { }, }, }, + }, { + name: "unknown url", + inputRequest: &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: resolutionframework.LabelValueFakeResolverType, + }, + }, + Spec: v1beta1.ResolutionRequestSpec{ + URL: "dne://does-not-exist", + }, + Status: v1beta1.ResolutionRequestStatus{}, + }, + expectedErr: errors.New("invalid resource request \"foo/rr\": Wrong url. Expected: fake://url, Got: dne://does-not-exist"), + }, { + name: "valid url", + inputRequest: &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: resolutionframework.LabelValueFakeResolverType, + }, + }, + Spec: v1beta1.ResolutionRequestSpec{ + URL: framework.FakeUrl, + }, + Status: v1beta1.ResolutionRequestStatus{}, + }, + paramMap: map[string]*resolutionframework.FakeResolvedResource{ + framework.FakeUrl: { + Content: "some content", + AnnotationMap: map[string]string{"foo": "bar"}, + ContentSource: &pipelinev1.RefSource{ + URI: "https://abc.com", + Digest: map[string]string{ + "sha1": "xyz", + }, + EntryPoint: "foo/bar", + }, + }, + }, + expectedStatus: &v1beta1.ResolutionRequestStatus{ + Status: duckv1.Status{ + Annotations: map[string]string{ + "foo": "bar", + }, + }, + ResolutionRequestStatusFields: v1beta1.ResolutionRequestStatusFields{ + Data: base64.StdEncoding.Strict().EncodeToString([]byte("some content")), + RefSource: &pipelinev1.RefSource{ + URI: "https://abc.com", + Digest: map[string]string{ + "sha1": "xyz", + }, + EntryPoint: "foo/bar", + }, + Source: &pipelinev1.RefSource{ + URI: "https://abc.com", + Digest: map[string]string{ + "sha1": "xyz", + }, + EntryPoint: "foo/bar", + }, + }, + }, + }, { + name: "resource not found for url", + inputRequest: &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: resolutionframework.LabelValueFakeResolverType, + }, + }, + Spec: v1beta1.ResolutionRequestSpec{ + URL: framework.FakeUrl, + }, + Status: v1beta1.ResolutionRequestStatus{}, + }, + paramMap: map[string]*resolutionframework.FakeResolvedResource{ + "other://resource": { + Content: "some content", + AnnotationMap: map[string]string{"foo": "bar"}, + ContentSource: &pipelinev1.RefSource{ + URI: "https://abc.com", + Digest: map[string]string{ + "sha1": "xyz", + }, + EntryPoint: "foo/bar", + }, + }, + }, + expectedErr: errors.New("error getting \"Fake\" \"foo/rr\": couldn't find resource for url fake://url"), + }, { + name: "invalid params", + inputRequest: &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: resolutionframework.LabelValueFakeResolverType, + }, + }, + Spec: v1beta1.ResolutionRequestSpec{ + Params: []pipelinev1.Param{{ + Name: "not-a-fake-param", + Value: *pipelinev1.NewStructuredValues("bar"), + }}, + }, + Status: v1beta1.ResolutionRequestStatus{}, + }, + expectedErr: errors.New(`invalid resource request "foo/rr": missing fake-key`), }, { name: "error resolving", inputRequest: &v1beta1.ResolutionRequest{ diff --git a/pkg/remoteresolution/resolver/git/resolver.go b/pkg/remoteresolution/resolver/git/resolver.go index 8aa15b65bd0..7231f4b007c 100644 --- a/pkg/remoteresolution/resolver/git/resolver.go +++ b/pkg/remoteresolution/resolver/git/resolver.go @@ -97,28 +97,36 @@ func (r *Resolver) GetSelector(_ context.Context) map[string]string { // ValidateParams returns an error if the given parameter map is not // valid for a resource request targeting the gitresolver. func (r *Resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestSpec) error { - return git.ValidateParams(ctx, req.Params) + if len(req.Params) > 0 { + return git.ValidateParams(ctx, req.Params) + } + // Remove this error once validate url has been implemented. + return errors.New("cannot validate request. the Validate method has not been implemented.") } // Resolve performs the work of fetching a file from git given a map of // parameters. func (r *Resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (resolutionframework.ResolvedResource, error) { - origParams := req.Params + if len(req.Params) > 0 { + origParams := req.Params - if git.IsDisabled(ctx) { - return nil, errors.New(disabledError) - } + if git.IsDisabled(ctx) { + return nil, errors.New(disabledError) + } - params, err := git.PopulateDefaultParams(ctx, origParams) - if err != nil { - return nil, err - } + params, err := git.PopulateDefaultParams(ctx, origParams) + if err != nil { + return nil, err + } - if params[git.UrlParam] != "" { - return git.ResolveAnonymousGit(ctx, params) - } + if params[git.UrlParam] != "" { + return git.ResolveAnonymousGit(ctx, params) + } - return git.ResolveAPIGit(ctx, params, r.kubeClient, r.logger, r.cache, r.ttl, r.clientFunc) + return git.ResolveAPIGit(ctx, params, r.kubeClient, r.logger, r.cache, r.ttl, r.clientFunc) + } + // Remove this error once resolution of url has been implemented. + return nil, errors.New("the Resolve method has not been implemented.") } var _ resolutionframework.ConfigWatcher = &Resolver{} diff --git a/pkg/remoteresolution/resolver/http/resolver.go b/pkg/remoteresolution/resolver/http/resolver.go index 3a0a5d48f0c..ec106586d9c 100644 --- a/pkg/remoteresolution/resolver/http/resolver.go +++ b/pkg/remoteresolution/resolver/http/resolver.go @@ -81,20 +81,28 @@ func (r *Resolver) GetSelector(context.Context) map[string]string { // Validate ensures parameters from a request are as expected. func (r *Resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestSpec) error { - return http.ValidateParams(ctx, req.Params) + if len(req.Params) > 0 { + return http.ValidateParams(ctx, req.Params) + } + // Remove this error once validate url has been implemented. + return errors.New("cannot validate request. the Validate method has not been implemented.") } // Resolve uses the given params to resolve the requested file or resource. func (r *Resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (resolutionframework.ResolvedResource, error) { - oParams := req.Params - if http.IsDisabled(ctx) { - return nil, errors.New(disabledError) - } - - params, err := http.PopulateDefaultParams(ctx, oParams) - if err != nil { - return nil, err + if len(req.Params) > 0 { + oParams := req.Params + if http.IsDisabled(ctx) { + return nil, errors.New(disabledError) + } + + params, err := http.PopulateDefaultParams(ctx, oParams) + if err != nil { + return nil, err + } + + return http.FetchHttpResource(ctx, params, r.kubeClient, r.logger) } - - return http.FetchHttpResource(ctx, params, r.kubeClient, r.logger) + // Remove this error once resolution of url has been implemented. + return nil, errors.New("the Resolve method has not been implemented.") } diff --git a/pkg/remoteresolution/resolver/http/resolver_test.go b/pkg/remoteresolution/resolver/http/resolver_test.go index f6d4634822e..0c9a3fd2ec5 100644 --- a/pkg/remoteresolution/resolver/http/resolver_test.go +++ b/pkg/remoteresolution/resolver/http/resolver_test.go @@ -108,6 +108,9 @@ func TestValidate(t *testing.T) { params := map[string]string{} if tc.url != "nourl" { params[httpresolution.UrlParam] = tc.url + } else { + // inject a fake param so that it can validate that the url is actually missing. + params["foo"] = "bar" } req := v1beta1.ResolutionRequestSpec{ Params: toParams(params), @@ -160,6 +163,11 @@ func TestResolve(t *testing.T) { Name: httpresolution.UrlParam, Value: *pipelinev1.NewStructuredValues(svr.URL), }) + } else { + params = append(params, pipelinev1.Param{ + Name: "foo", + Value: *pipelinev1.NewStructuredValues("bar"), + }) } resolver := Resolver{} req := v1beta1.ResolutionRequestSpec{ @@ -199,7 +207,7 @@ func TestResolve(t *testing.T) { func TestResolveNotEnabled(t *testing.T) { var err error resolver := Resolver{} - someParams := map[string]string{} + someParams := map[string]string{"foo": "bar"} req := v1beta1.ResolutionRequestSpec{ Params: toParams(someParams), } @@ -210,7 +218,7 @@ func TestResolveNotEnabled(t *testing.T) { if d := cmp.Diff(disabledError, err.Error()); d != "" { t.Errorf("unexpected error: %s", diff.PrintWantGot(d)) } - err = resolver.Validate(resolverDisabledContext(), &v1beta1.ResolutionRequestSpec{Params: toParams(map[string]string{})}) + err = resolver.Validate(resolverDisabledContext(), &v1beta1.ResolutionRequestSpec{Params: toParams(someParams)}) if err == nil { t.Fatalf("expected disabled err") } diff --git a/pkg/remoteresolution/resolver/hub/resolver.go b/pkg/remoteresolution/resolver/hub/resolver.go index fbea8b32709..8c29b23e50d 100644 --- a/pkg/remoteresolution/resolver/hub/resolver.go +++ b/pkg/remoteresolution/resolver/hub/resolver.go @@ -15,6 +15,7 @@ package hub import ( "context" + "errors" "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" "github.com/tektoncd/pipeline/pkg/remoteresolution/resolver/framework" @@ -69,10 +70,18 @@ func (r *Resolver) GetSelector(context.Context) map[string]string { // Validate ensures parameters from a request are as expected. func (r *Resolver) Validate(ctx context.Context, req *v1beta1.ResolutionRequestSpec) error { - return hub.ValidateParams(ctx, req.Params, r.TektonHubURL) + if len(req.Params) > 0 { + return hub.ValidateParams(ctx, req.Params, r.TektonHubURL) + } + // Remove this error once validate url has been implemented. + return errors.New("cannot validate request. the Validate method has not been implemented.") } // Resolve uses the given params to resolve the requested file or resource. func (r *Resolver) Resolve(ctx context.Context, req *v1beta1.ResolutionRequestSpec) (resolutionframework.ResolvedResource, error) { - return hub.Resolve(ctx, req.Params, r.TektonHubURL, r.ArtifactHubURL) + if len(req.Params) > 0 { + return hub.Resolve(ctx, req.Params, r.TektonHubURL, r.ArtifactHubURL) + } + // Remove this error once resolution of url has been implemented. + return nil, errors.New("the Resolve method has not been implemented.") } diff --git a/pkg/remoteresolution/resource/crd_resource.go b/pkg/remoteresolution/resource/crd_resource.go index 017654ca005..55c619f7d48 100644 --- a/pkg/remoteresolution/resource/crd_resource.go +++ b/pkg/remoteresolution/resource/crd_resource.go @@ -87,6 +87,7 @@ func (r *CRDRequester) createResolutionRequest(ctx context.Context, resolver Res owner = ownedReq.OwnerRef() } rr := resolutionresource.CreateResolutionRequest(ctx, resolver, req.ResolverPayload().Name, req.ResolverPayload().Namespace, req.ResolverPayload().ResolutionSpec.Params, owner) + rr.Spec.URL = req.ResolverPayload().ResolutionSpec.URL _, err := r.clientset.ResolutionV1beta1().ResolutionRequests(rr.Namespace).Create(ctx, rr, metav1.CreateOptions{}) return err } diff --git a/pkg/remoteresolution/resource/crd_resource_test.go b/pkg/remoteresolution/resource/crd_resource_test.go index 6bc4150e67e..728a52b73b7 100644 --- a/pkg/remoteresolution/resource/crd_resource_test.go +++ b/pkg/remoteresolution/resource/crd_resource_test.go @@ -78,6 +78,7 @@ resolverPayload: value: main - name: pathInRepo value: task/git-clone/0.6/git-clone.yaml + url: "https://foo/bar" `) baseRR := mustParseResolutionRequest(t, ` kind: "ResolutionRequest" @@ -102,6 +103,7 @@ spec: value: "main" - name: "pathInRepo" value: "task/git-clone/0.6/git-clone.yaml" + url: "https://foo/bar" `) createdRR := baseRR.DeepCopy() // diff --git a/pkg/remoteresolution/resource/request_test.go b/pkg/remoteresolution/resource/request_test.go index e387070345b..664f66cc423 100644 --- a/pkg/remoteresolution/resource/request_test.go +++ b/pkg/remoteresolution/resource/request_test.go @@ -40,6 +40,7 @@ func TestNewRequest(t *testing.T) { {Name: "param1", Value: v1.ParamValue{Type: v1.ParamTypeString, StringVal: "value1"}}, {Name: "param2", Value: v1.ParamValue{Type: v1.ParamTypeString, StringVal: "value2"}}, }, + URL: "https://foo/bar", }, }, } diff --git a/pkg/resolution/resource/name.go b/pkg/resolution/resource/name.go index eef3cb88afb..f93e0814e2e 100644 --- a/pkg/resolution/resource/name.go +++ b/pkg/resolution/resource/name.go @@ -105,6 +105,11 @@ func GenerateDeterministicNameFromSpec(prefix, base string, resolutionSpec *v1be } } } + if len(resolutionSpec.URL) > 0 { + if _, err := hasher.Write([]byte(resolutionSpec.URL)); err != nil { + return "", err + } + } name := fmt.Sprintf("%s-%x", prefix, hasher.Sum(nil)) if maxLength > len(name) { return name, nil diff --git a/pkg/resolution/resource/name_test.go b/pkg/resolution/resource/name_test.go index 1a90a0aaf18..95bb8c3afe1 100644 --- a/pkg/resolution/resource/name_test.go +++ b/pkg/resolution/resource/name_test.go @@ -20,6 +20,7 @@ import ( "testing" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" + "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" "github.com/tektoncd/pipeline/pkg/resolution/resource" ) @@ -113,3 +114,107 @@ func TestGenerateDeterministicName(t *testing.T) { }) } } + +func TestGenerateDeterministicNameFromSpec(t *testing.T) { + type args struct { + prefix string + base string + params []v1.Param + url string + } + golden := args{ + prefix: "prefix", + base: "base", + params: []v1.Param{ + { + Name: "string-param", + Value: v1.ParamValue{ + Type: v1.ParamTypeString, + StringVal: "value1", + }, + }, + { + Name: "array-param", + Value: v1.ParamValue{ + Type: v1.ParamTypeArray, + ArrayVal: []string{"value1", "value2"}, + }, + }, + { + Name: "object-param", + Value: v1.ParamValue{ + Type: v1.ParamTypeObject, + ObjectVal: map[string]string{"key": "value"}, + }, + }, + }, + url: "https://foo/bar", + } + tests := []struct { + name string + args args + want string + wantErr bool + }{ + { + name: "only contains prefix", + args: args{ + prefix: golden.prefix, + }, + want: "prefix-6c62272e07bb014262b821756295c58d", + }, + { + name: "only contains base", + args: args{ + base: golden.base, + }, + want: "-6989337ae0757277b806e97e86444ef0", + }, + { + name: "only contains url", + args: args{ + url: golden.url, + }, + want: "-dcfaf53735f4a84a3e319e17352940b4", + }, + { + name: "only contains params", + args: args{ + params: golden.params, + }, + want: "-52921b17d3c2930a34419c618d6af0e9", + }, + { + name: "params with different order should generate same hash", + args: args{ + params: []v1.Param{ + golden.params[2], + golden.params[1], + golden.params[0], + }, + }, + want: "-52921b17d3c2930a34419c618d6af0e9", + }, + { + name: "contain all fields", + args: golden, + want: "prefix-ff25bd24688ab610bdc530a5ab3aabbd", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + resolutionSpec := &v1beta1.ResolutionRequestSpec{ + Params: tt.args.params, + URL: tt.args.url, + } + got, err := resource.GenerateDeterministicNameFromSpec(tt.args.prefix, tt.args.base, resolutionSpec) + if (err != nil) != tt.wantErr { + t.Errorf("GenerateDeterministicNameFromSpec() error = %v, wantErr %v", err, tt.wantErr) + return + } + if got != tt.want { + t.Errorf("GenerateDeterministicNameFromSpec() = %v, want %v", got, tt.want) + } + }) + } +} diff --git a/test/e2e-tests-kind-prow-alpha.env b/test/e2e-tests-kind-prow-alpha.env index 255bdf63579..dfcc2e76444 100644 --- a/test/e2e-tests-kind-prow-alpha.env +++ b/test/e2e-tests-kind-prow-alpha.env @@ -8,3 +8,4 @@ ENABLE_STEP_ACTIONS=true ENABLE_CEL_IN_WHENEXPRESSION=true ENABLE_PARAM_ENUM=true ENABLE_ARTIFACTS=true +ENABLE_CONCISE_RESOLVER_SYNTAX=true diff --git a/test/e2e-tests.sh b/test/e2e-tests.sh index a291f27e4ba..8a8b63a48eb 100755 --- a/test/e2e-tests.sh +++ b/test/e2e-tests.sh @@ -32,6 +32,7 @@ ENABLE_STEP_ACTIONS=${ENABLE_STEP_ACTIONS:="false"} ENABLE_CEL_IN_WHENEXPRESSION=${ENABLE_CEL_IN_WHENEXPRESSION:="false"} ENABLE_PARAM_ENUM=${ENABLE_PARAM_ENUM:="false"} ENABLE_ARTIFACTS=${ENABLE_ARTIFACTS:="false"} +ENABLE_CONCISE_RESOLVER_SYNTAX=${ENABLE_CONCISE_RESOLVER_SYNTAX:="false"} failed=0 # Script entry point. @@ -130,6 +131,18 @@ function set_enable_artifacts() { kubectl patch configmap feature-flags -n tekton-pipelines -p "$jsonpatch" } +function set_enable_concise_resolver_syntax() { + local method="$1" + if [ "$method" != "false" ] && [ "$method" != "true" ]; then + printf "Invalid value for enable-concise-resolver-syntax %s\n" ${method} + exit 255 + fi + printf "Setting enable-concise-resolver-syntax to %s\n", ${method} + jsonpatch=$(printf "{\"data\": {\"enable-concise-resolver-syntax\": \"%s\"}}" $1) + echo "feature-flags ConfigMap patch: ${jsonpatch}" + kubectl patch configmap feature-flags -n tekton-pipelines -p "$jsonpatch" +} + function run_e2e() { # Run the integration tests header "Running Go e2e tests" @@ -157,6 +170,7 @@ set_enable_step_actions "$ENABLE_STEP_ACTIONS" set_cel_in_whenexpression "$ENABLE_CEL_IN_WHENEXPRESSION" set_enable_param_enum "$ENABLE_PARAM_ENUM" set_enable_artifacts "$ENABLE_ARTIFACTS" +set_enable_concise_resolver_syntax "$ENABLE_CONCISE_RESOLVER_SYNTAX" run_e2e (( failed )) && fail_test diff --git a/test/featureflags.go b/test/featureflags.go index 6ffa121f0ed..0f5cd810ff0 100644 --- a/test/featureflags.go +++ b/test/featureflags.go @@ -111,13 +111,14 @@ func requireAllGates(gates map[string]string) func(context.Context, *testing.T, func getFeatureFlagsBaseOnAPIFlag(t *testing.T) *config.FeatureFlags { t.Helper() alphaFeatureFlags, err := config.NewFeatureFlagsFromMap(map[string]string{ - "enable-api-fields": "alpha", - "results-from": "sidecar-logs", - "enable-tekton-oci-bundles": "true", - "enable-step-actions": "true", - "enable-cel-in-whenexpression": "true", - "enable-param-enum": "true", - "enable-artifacts": "true", + "enable-api-fields": "alpha", + "results-from": "sidecar-logs", + "enable-tekton-oci-bundles": "true", + "enable-step-actions": "true", + "enable-cel-in-whenexpression": "true", + "enable-param-enum": "true", + "enable-artifacts": "true", + "enable-concise-resolver-syntax": "true", }) if err != nil { t.Fatalf("error creating alpha feature flags configmap: %v", err) diff --git a/test/remoteresolution/resolution.go b/test/remoteresolution/resolution.go index daefaed94ea..05274a7a182 100644 --- a/test/remoteresolution/resolution.go +++ b/test/remoteresolution/resolution.go @@ -73,7 +73,9 @@ func (r *Requester) Submit(ctx context.Context, resolverName resolution.Resolver if (r.ResolverPayload == resource.ResolverPayload{} || r.ResolverPayload.ResolutionSpec == nil || len(r.ResolverPayload.ResolutionSpec.Params) == 0) { return r.ResolvedResource, r.SubmitErr } - + if r.ResolverPayload.ResolutionSpec.URL == "" { + return r.ResolvedResource, r.SubmitErr + } reqParams := make(map[string]pipelinev1.ParamValue) for _, p := range req.ResolverPayload().ResolutionSpec.Params { reqParams[p.Name] = p.Value @@ -90,6 +92,9 @@ func (r *Requester) Submit(ctx context.Context, resolverName resolution.Resolver if len(wrongParams) > 0 { return nil, errors.New(strings.Join(wrongParams, "; ")) } + if r.ResolverPayload.ResolutionSpec.URL != req.ResolverPayload().ResolutionSpec.URL { + return nil, fmt.Errorf("Resolution name did not match. Got %s; Want %s", req.ResolverPayload().ResolutionSpec.URL, r.ResolverPayload.ResolutionSpec.URL) + } return r.ResolvedResource, r.SubmitErr } From 4b50e4cf216ea4ae587fe064615c0751ea56c8a3 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 May 2024 18:32:03 +0000 Subject: [PATCH 12/23] chore(deps): bump github.com/spiffe/spire-api-sdk from 1.9.4 to 1.9.6 Bumps [github.com/spiffe/spire-api-sdk](https://github.com/spiffe/spire-api-sdk) from 1.9.4 to 1.9.6. - [Commits](https://github.com/spiffe/spire-api-sdk/compare/v1.9.4...v1.9.6) --- updated-dependencies: - dependency-name: github.com/spiffe/spire-api-sdk dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- go.mod | 2 +- go.sum | 4 +- .../spire/api/server/entry/v1/entry.pb.go | 695 +++++++++++------- .../spire/api/server/entry/v1/entry.proto | 12 + vendor/modules.txt | 2 +- 5 files changed, 444 insertions(+), 271 deletions(-) diff --git a/go.mod b/go.mod index 8997d908004..9ca27598604 100644 --- a/go.mod +++ b/go.mod @@ -20,7 +20,7 @@ require ( github.com/pkg/errors v0.9.1 github.com/sigstore/sigstore v1.8.3 github.com/spiffe/go-spiffe/v2 v2.2.0 - github.com/spiffe/spire-api-sdk v1.9.4 + github.com/spiffe/spire-api-sdk v1.9.6 github.com/tektoncd/plumbing v0.0.0-20220817140952-3da8ce01aeeb go.opencensus.io v0.24.0 go.uber.org/zap v1.27.0 diff --git a/go.sum b/go.sum index 555f8379241..2e614576bec 100644 --- a/go.sum +++ b/go.sum @@ -1084,8 +1084,8 @@ github.com/spf13/viper v1.4.0/go.mod h1:PTJ7Z/lr49W6bUbkmS1V3by4uWynFiR9p7+dSq/y github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/spiffe/go-spiffe/v2 v2.2.0 h1:9Vf06UsvsDbLYK/zJ4sYsIsHmMFknUD+feA7IYoWMQY= github.com/spiffe/go-spiffe/v2 v2.2.0/go.mod h1:Urzb779b3+IwDJD2ZbN8fVl3Aa8G4N/PiUe6iXC0XxU= -github.com/spiffe/spire-api-sdk v1.9.4 h1:SbC37G2vwX/ojULl+avWvye4ITHYBorcC7+8ExWpNjA= -github.com/spiffe/spire-api-sdk v1.9.4/go.mod h1:4uuhFlN6KBWjACRP3xXwrOTNnvaLp1zJs8Lribtr4fI= +github.com/spiffe/spire-api-sdk v1.9.6 h1:scy7dQOh/H0Fxqmy1vJyY3rGlA3ryDfHRqVpo56UZhE= +github.com/spiffe/spire-api-sdk v1.9.6/go.mod h1:4uuhFlN6KBWjACRP3xXwrOTNnvaLp1zJs8Lribtr4fI= github.com/src-d/gcfg v1.4.0/go.mod h1:p/UMsR43ujA89BJY9duynAwIpvqEujIH/jFlfL7jWoI= github.com/stefanberger/go-pkcs11uri v0.0.0-20201008174630-78d3cae3a980/go.mod h1:AO3tvPzVZ/ayst6UlUKUv6rcPQInYe3IknH3jYhAKu8= github.com/stoewer/go-strcase v1.2.0 h1:Z2iHWqGXH00XYgqDmNgQbIBxf3wrNq0F3feEy0ainaU= diff --git a/vendor/github.com/spiffe/spire-api-sdk/proto/spire/api/server/entry/v1/entry.pb.go b/vendor/github.com/spiffe/spire-api-sdk/proto/spire/api/server/entry/v1/entry.pb.go index 1376ba7a8b6..fd081d5d294 100644 --- a/vendor/github.com/spiffe/spire-api-sdk/proto/spire/api/server/entry/v1/entry.pb.go +++ b/vendor/github.com/spiffe/spire-api-sdk/proto/spire/api/server/entry/v1/entry.pb.go @@ -26,6 +26,9 @@ type CountEntriesRequest struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache unknownFields protoimpl.UnknownFields + + // Filters the entries returned in the response. + Filter *CountEntriesRequest_Filter `protobuf:"bytes,1,opt,name=filter,proto3" json:"filter,omitempty"` } func (x *CountEntriesRequest) Reset() { @@ -60,6 +63,13 @@ func (*CountEntriesRequest) Descriptor() ([]byte, []int) { return file_spire_api_server_entry_v1_entry_proto_rawDescGZIP(), []int{0} } +func (x *CountEntriesRequest) GetFilter() *CountEntriesRequest_Filter { + if x != nil { + return x.Filter + } + return nil +} + type CountEntriesResponse struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -901,6 +911,93 @@ func (x *EntryRevision) GetRevisionNumber() int64 { return 0 } +type CountEntriesRequest_Filter struct { + state protoimpl.MessageState + sizeCache protoimpl.SizeCache + unknownFields protoimpl.UnknownFields + + BySpiffeId *types.SPIFFEID `protobuf:"bytes,1,opt,name=by_spiffe_id,json=bySpiffeId,proto3" json:"by_spiffe_id,omitempty"` + ByParentId *types.SPIFFEID `protobuf:"bytes,2,opt,name=by_parent_id,json=byParentId,proto3" json:"by_parent_id,omitempty"` + BySelectors *types.SelectorMatch `protobuf:"bytes,3,opt,name=by_selectors,json=bySelectors,proto3" json:"by_selectors,omitempty"` + ByFederatesWith *types.FederatesWithMatch `protobuf:"bytes,4,opt,name=by_federates_with,json=byFederatesWith,proto3" json:"by_federates_with,omitempty"` + ByHint *wrapperspb.StringValue `protobuf:"bytes,5,opt,name=by_hint,json=byHint,proto3" json:"by_hint,omitempty"` + ByDownstream *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=by_downstream,json=byDownstream,proto3" json:"by_downstream,omitempty"` +} + +func (x *CountEntriesRequest_Filter) Reset() { + *x = CountEntriesRequest_Filter{} + if protoimpl.UnsafeEnabled { + mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[16] + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + ms.StoreMessageInfo(mi) + } +} + +func (x *CountEntriesRequest_Filter) String() string { + return protoimpl.X.MessageStringOf(x) +} + +func (*CountEntriesRequest_Filter) ProtoMessage() {} + +func (x *CountEntriesRequest_Filter) ProtoReflect() protoreflect.Message { + mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[16] + if protoimpl.UnsafeEnabled && x != nil { + ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) + if ms.LoadMessageInfo() == nil { + ms.StoreMessageInfo(mi) + } + return ms + } + return mi.MessageOf(x) +} + +// Deprecated: Use CountEntriesRequest_Filter.ProtoReflect.Descriptor instead. +func (*CountEntriesRequest_Filter) Descriptor() ([]byte, []int) { + return file_spire_api_server_entry_v1_entry_proto_rawDescGZIP(), []int{0, 0} +} + +func (x *CountEntriesRequest_Filter) GetBySpiffeId() *types.SPIFFEID { + if x != nil { + return x.BySpiffeId + } + return nil +} + +func (x *CountEntriesRequest_Filter) GetByParentId() *types.SPIFFEID { + if x != nil { + return x.ByParentId + } + return nil +} + +func (x *CountEntriesRequest_Filter) GetBySelectors() *types.SelectorMatch { + if x != nil { + return x.BySelectors + } + return nil +} + +func (x *CountEntriesRequest_Filter) GetByFederatesWith() *types.FederatesWithMatch { + if x != nil { + return x.ByFederatesWith + } + return nil +} + +func (x *CountEntriesRequest_Filter) GetByHint() *wrapperspb.StringValue { + if x != nil { + return x.ByHint + } + return nil +} + +func (x *CountEntriesRequest_Filter) GetByDownstream() *wrapperspb.BoolValue { + if x != nil { + return x.ByDownstream + } + return nil +} + type ListEntriesRequest_Filter struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -911,12 +1008,13 @@ type ListEntriesRequest_Filter struct { BySelectors *types.SelectorMatch `protobuf:"bytes,3,opt,name=by_selectors,json=bySelectors,proto3" json:"by_selectors,omitempty"` ByFederatesWith *types.FederatesWithMatch `protobuf:"bytes,4,opt,name=by_federates_with,json=byFederatesWith,proto3" json:"by_federates_with,omitempty"` ByHint *wrapperspb.StringValue `protobuf:"bytes,5,opt,name=by_hint,json=byHint,proto3" json:"by_hint,omitempty"` + ByDownstream *wrapperspb.BoolValue `protobuf:"bytes,6,opt,name=by_downstream,json=byDownstream,proto3" json:"by_downstream,omitempty"` } func (x *ListEntriesRequest_Filter) Reset() { *x = ListEntriesRequest_Filter{} if protoimpl.UnsafeEnabled { - mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[16] + mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[17] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -929,7 +1027,7 @@ func (x *ListEntriesRequest_Filter) String() string { func (*ListEntriesRequest_Filter) ProtoMessage() {} func (x *ListEntriesRequest_Filter) ProtoReflect() protoreflect.Message { - mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[16] + mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[17] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -980,6 +1078,13 @@ func (x *ListEntriesRequest_Filter) GetByHint() *wrapperspb.StringValue { return nil } +func (x *ListEntriesRequest_Filter) GetByDownstream() *wrapperspb.BoolValue { + if x != nil { + return x.ByDownstream + } + return nil +} + type BatchCreateEntryResponse_Result struct { state protoimpl.MessageState sizeCache protoimpl.SizeCache @@ -999,7 +1104,7 @@ type BatchCreateEntryResponse_Result struct { func (x *BatchCreateEntryResponse_Result) Reset() { *x = BatchCreateEntryResponse_Result{} if protoimpl.UnsafeEnabled { - mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[17] + mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[18] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1012,7 +1117,7 @@ func (x *BatchCreateEntryResponse_Result) String() string { func (*BatchCreateEntryResponse_Result) ProtoMessage() {} func (x *BatchCreateEntryResponse_Result) ProtoReflect() protoreflect.Message { - mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[17] + mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[18] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1058,7 +1163,7 @@ type BatchUpdateEntryResponse_Result struct { func (x *BatchUpdateEntryResponse_Result) Reset() { *x = BatchUpdateEntryResponse_Result{} if protoimpl.UnsafeEnabled { - mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[18] + mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[19] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1071,7 +1176,7 @@ func (x *BatchUpdateEntryResponse_Result) String() string { func (*BatchUpdateEntryResponse_Result) ProtoMessage() {} func (x *BatchUpdateEntryResponse_Result) ProtoReflect() protoreflect.Message { - mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[18] + mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[19] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1115,7 +1220,7 @@ type BatchDeleteEntryResponse_Result struct { func (x *BatchDeleteEntryResponse_Result) Reset() { *x = BatchDeleteEntryResponse_Result{} if protoimpl.UnsafeEnabled { - mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[19] + mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[20] ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) ms.StoreMessageInfo(mi) } @@ -1128,7 +1233,7 @@ func (x *BatchDeleteEntryResponse_Result) String() string { func (*BatchDeleteEntryResponse_Result) ProtoMessage() {} func (x *BatchDeleteEntryResponse_Result) ProtoReflect() protoreflect.Message { - mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[19] + mi := &file_spire_api_server_entry_v1_entry_proto_msgTypes[20] if protoimpl.UnsafeEnabled && x != nil { ms := protoimpl.X.MessageStateOf(protoimpl.Pointer(x)) if ms.LoadMessageInfo() == nil { @@ -1177,99 +1282,107 @@ var file_spire_api_server_entry_v1_entry_proto_rawDesc = []byte{ 0x74, 0x79, 0x70, 0x65, 0x73, 0x2f, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x1a, 0x1e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2f, 0x77, 0x72, 0x61, 0x70, 0x70, 0x65, 0x72, 0x73, 0x2e, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x22, 0x15, 0x0a, 0x13, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x22, 0x2c, 0x0a, 0x14, 0x43, 0x6f, 0x75, - 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, - 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, - 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xab, 0x04, 0x0a, 0x12, 0x4c, 0x69, 0x73, 0x74, - 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4c, - 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x34, - 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, - 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, - 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x0b, - 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, - 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x6f, - 0x75, 0x74, 0x70, 0x75, 0x74, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, 0x67, - 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, 0x61, - 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, - 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, 0x65, - 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0xcd, 0x02, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, 0x72, - 0x12, 0x3b, 0x0a, 0x0c, 0x62, 0x79, 0x5f, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x5f, 0x69, 0x64, - 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, 0x49, - 0x44, 0x52, 0x0a, 0x62, 0x79, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x49, 0x64, 0x12, 0x3b, 0x0a, - 0x0c, 0x62, 0x79, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, 0x49, 0x44, 0x52, 0x0a, - 0x62, 0x79, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x41, 0x0a, 0x0c, 0x62, 0x79, - 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, - 0x32, 0x1e, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, - 0x65, 0x73, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x4d, 0x61, 0x74, 0x63, 0x68, - 0x52, 0x0b, 0x62, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x4f, 0x0a, - 0x11, 0x62, 0x79, 0x5f, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x73, 0x5f, 0x77, 0x69, - 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, - 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x46, 0x65, 0x64, 0x65, 0x72, - 0x61, 0x74, 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x0f, 0x62, - 0x79, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x12, 0x35, - 0x0a, 0x07, 0x62, 0x79, 0x5f, 0x68, 0x69, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, - 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, 0x62, - 0x79, 0x48, 0x69, 0x6e, 0x74, 0x22, 0x6f, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, - 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x07, - 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x26, - 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, 0x61, 0x67, - 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x5e, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, - 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3b, 0x0a, 0x0b, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x88, 0x01, 0x0a, 0x17, 0x42, 0x61, 0x74, 0x63, 0x68, - 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, - 0x73, 0x74, 0x12, 0x30, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, - 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, - 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, - 0x72, 0x69, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6d, - 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x70, 0x69, 0x72, - 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4d, 0x61, 0x73, - 0x6b, 0x22, 0xd9, 0x01, 0x0a, 0x18, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, - 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, - 0x3a, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, - 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, - 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, - 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x1a, 0x67, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2f, - 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, - 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x2c, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, - 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, 0xc3, 0x01, - 0x0a, 0x17, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x07, 0x65, 0x6e, 0x74, - 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x70, 0x69, - 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, - 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x0a, 0x69, - 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, - 0x1a, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, - 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x09, 0x69, 0x6e, 0x70, - 0x75, 0x74, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x3b, 0x0a, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, - 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x70, + 0x74, 0x6f, 0x22, 0xf5, 0x03, 0x0a, 0x13, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72, + 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x4d, 0x0a, 0x06, 0x66, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x35, 0x2e, 0x73, 0x70, 0x69, + 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, + 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72, + 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x1a, 0x8e, 0x03, 0x0a, 0x06, 0x46, 0x69, + 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3b, 0x0a, 0x0c, 0x62, 0x79, 0x5f, 0x73, 0x70, 0x69, 0x66, 0x66, + 0x65, 0x5f, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x70, 0x69, + 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x50, 0x49, + 0x46, 0x46, 0x45, 0x49, 0x44, 0x52, 0x0a, 0x62, 0x79, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x49, + 0x64, 0x12, 0x3b, 0x0a, 0x0c, 0x62, 0x79, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, + 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, + 0x49, 0x44, 0x52, 0x0a, 0x62, 0x79, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x41, + 0x0a, 0x0c, 0x62, 0x79, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x03, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x4d, + 0x61, 0x74, 0x63, 0x68, 0x52, 0x0b, 0x62, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, + 0x73, 0x12, 0x4f, 0x0a, 0x11, 0x62, 0x79, 0x5f, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, + 0x73, 0x5f, 0x77, 0x69, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, + 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x46, + 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, + 0x68, 0x52, 0x0f, 0x62, 0x79, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x73, 0x57, 0x69, + 0x74, 0x68, 0x12, 0x35, 0x0a, 0x07, 0x62, 0x79, 0x5f, 0x68, 0x69, 0x6e, 0x74, 0x18, 0x05, 0x20, + 0x01, 0x28, 0x0b, 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, + 0x65, 0x52, 0x06, 0x62, 0x79, 0x48, 0x69, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x0d, 0x62, 0x79, 0x5f, + 0x64, 0x6f, 0x77, 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x62, 0x79, + 0x44, 0x6f, 0x77, 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0x2c, 0x0a, 0x14, 0x43, 0x6f, + 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x14, 0x0a, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x05, 0x52, 0x05, 0x63, 0x6f, 0x75, 0x6e, 0x74, 0x22, 0xec, 0x04, 0x0a, 0x12, 0x4c, 0x69, 0x73, + 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, + 0x4c, 0x0a, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x34, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, + 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x2e, 0x46, + 0x69, 0x6c, 0x74, 0x65, 0x72, 0x52, 0x06, 0x66, 0x69, 0x6c, 0x74, 0x65, 0x72, 0x12, 0x3b, 0x0a, + 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, + 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x1b, 0x0a, 0x09, 0x70, 0x61, + 0x67, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x05, 0x52, 0x08, 0x70, + 0x61, 0x67, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x1d, 0x0a, 0x0a, 0x70, 0x61, 0x67, 0x65, 0x5f, + 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x04, 0x20, 0x01, 0x28, 0x09, 0x52, 0x09, 0x70, 0x61, 0x67, + 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x1a, 0x8e, 0x03, 0x0a, 0x06, 0x46, 0x69, 0x6c, 0x74, 0x65, + 0x72, 0x12, 0x3b, 0x0a, 0x0c, 0x62, 0x79, 0x5f, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x5f, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, + 0x49, 0x44, 0x52, 0x0a, 0x62, 0x79, 0x53, 0x70, 0x69, 0x66, 0x66, 0x65, 0x49, 0x64, 0x12, 0x3b, + 0x0a, 0x0c, 0x62, 0x79, 0x5f, 0x70, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x5f, 0x69, 0x64, 0x18, 0x02, + 0x20, 0x01, 0x28, 0x0b, 0x32, 0x19, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x50, 0x49, 0x46, 0x46, 0x45, 0x49, 0x44, 0x52, + 0x0a, 0x62, 0x79, 0x50, 0x61, 0x72, 0x65, 0x6e, 0x74, 0x49, 0x64, 0x12, 0x41, 0x0a, 0x0c, 0x62, + 0x79, 0x5f, 0x73, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1e, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x4d, 0x61, 0x74, 0x63, + 0x68, 0x52, 0x0b, 0x62, 0x79, 0x53, 0x65, 0x6c, 0x65, 0x63, 0x74, 0x6f, 0x72, 0x73, 0x12, 0x4f, + 0x0a, 0x11, 0x62, 0x79, 0x5f, 0x66, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x73, 0x5f, 0x77, + 0x69, 0x74, 0x68, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x73, 0x70, 0x69, 0x72, + 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x46, 0x65, 0x64, 0x65, + 0x72, 0x61, 0x74, 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x4d, 0x61, 0x74, 0x63, 0x68, 0x52, 0x0f, + 0x62, 0x79, 0x46, 0x65, 0x64, 0x65, 0x72, 0x61, 0x74, 0x65, 0x73, 0x57, 0x69, 0x74, 0x68, 0x12, + 0x35, 0x0a, 0x07, 0x62, 0x79, 0x5f, 0x68, 0x69, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1c, 0x2e, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, + 0x75, 0x66, 0x2e, 0x53, 0x74, 0x72, 0x69, 0x6e, 0x67, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x06, + 0x62, 0x79, 0x48, 0x69, 0x6e, 0x74, 0x12, 0x3f, 0x0a, 0x0d, 0x62, 0x79, 0x5f, 0x64, 0x6f, 0x77, + 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x62, 0x75, 0x66, 0x2e, + 0x42, 0x6f, 0x6f, 0x6c, 0x56, 0x61, 0x6c, 0x75, 0x65, 0x52, 0x0c, 0x62, 0x79, 0x44, 0x6f, 0x77, + 0x6e, 0x73, 0x74, 0x72, 0x65, 0x61, 0x6d, 0x22, 0x6f, 0x0a, 0x13, 0x4c, 0x69, 0x73, 0x74, 0x45, + 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, + 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x12, 0x26, 0x0a, 0x0f, 0x6e, 0x65, 0x78, 0x74, 0x5f, 0x70, 0x61, 0x67, 0x65, 0x5f, 0x74, 0x6f, + 0x6b, 0x65, 0x6e, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0d, 0x6e, 0x65, 0x78, 0x74, 0x50, + 0x61, 0x67, 0x65, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0x5e, 0x0a, 0x0f, 0x47, 0x65, 0x74, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x0e, 0x0a, 0x02, 0x69, + 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x3b, 0x0a, 0x0b, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x88, 0x01, 0x0a, 0x17, 0x42, 0x61, 0x74, + 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, + 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, + 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, + 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x3b, 0x0a, 0x0b, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, + 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x70, 0x75, 0x74, 0x4d, - 0x61, 0x73, 0x6b, 0x22, 0xd9, 0x01, 0x0a, 0x18, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, + 0x61, 0x73, 0x6b, 0x22, 0xd9, 0x01, 0x0a, 0x18, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, - 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, + 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, 0x67, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, @@ -1278,121 +1391,147 @@ var file_spire_api_server_entry_v1_entry_proto_rawDesc = []byte{ 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x22, - 0x2b, 0x0a, 0x17, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0xbb, 0x01, 0x0a, - 0x18, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x07, 0x72, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x73, 0x70, 0x69, - 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, - 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, - 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, - 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, - 0x49, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, - 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x70, 0x69, 0x72, - 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, - 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x5a, 0x0a, 0x1b, 0x47, 0x65, - 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x0b, 0x6f, 0x75, 0x74, - 0x70, 0x75, 0x74, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, - 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, - 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x50, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, - 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, - 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, - 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0x6d, 0x0a, 0x1c, 0x53, 0x79, 0x6e, 0x63, - 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, - 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x0b, 0x6f, 0x75, 0x74, 0x70, - 0x75, 0x74, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, + 0xc3, 0x01, 0x0a, 0x17, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x30, 0x0a, 0x07, 0x65, + 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, + 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, + 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x39, 0x0a, + 0x0a, 0x69, 0x6e, 0x70, 0x75, 0x74, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x02, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, + 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x09, 0x69, + 0x6e, 0x70, 0x75, 0x74, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x3b, 0x0a, 0x0b, 0x6f, 0x75, 0x74, 0x70, + 0x75, 0x74, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x6f, 0x75, 0x74, 0x70, 0x75, - 0x74, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x02, 0x20, 0x03, - 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0xb8, 0x01, 0x0a, 0x1d, 0x53, 0x79, 0x6e, 0x63, - 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, - 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0f, 0x65, 0x6e, 0x74, - 0x72, 0x79, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, 0x20, 0x03, - 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, - 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0e, 0x65, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, 0x0a, 0x07, - 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, - 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x12, - 0x0a, 0x04, 0x6d, 0x6f, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, 0x6d, 0x6f, - 0x72, 0x65, 0x22, 0x48, 0x0a, 0x0d, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x76, 0x69, 0x73, - 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x5f, - 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, 0x72, 0x65, - 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x32, 0xc8, 0x07, 0x0a, - 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x6f, 0x0a, 0x0c, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, - 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2e, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, - 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, - 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, - 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x0b, 0x4c, 0x69, 0x73, 0x74, 0x45, - 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2d, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, - 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, - 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, - 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, - 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, - 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x2a, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, - 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x16, 0x2e, - 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x7b, 0x0a, 0x10, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, - 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x32, 0x2e, 0x73, 0x70, 0x69, 0x72, - 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, - 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, - 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, - 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, - 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, - 0x73, 0x65, 0x12, 0x7b, 0x0a, 0x10, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, - 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x32, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, - 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, - 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x73, 0x70, 0x69, - 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, - 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, - 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, - 0x7b, 0x0a, 0x10, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, - 0x74, 0x72, 0x79, 0x12, 0x32, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x74, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0xd9, 0x01, 0x0a, 0x18, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, + 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, + 0x73, 0x65, 0x12, 0x54, 0x0a, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, + 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, - 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, - 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, + 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, + 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x1a, 0x67, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, + 0x6c, 0x74, 0x12, 0x2f, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, + 0x74, 0x75, 0x73, 0x12, 0x2c, 0x0a, 0x05, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, + 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x05, 0x65, 0x6e, 0x74, 0x72, + 0x79, 0x22, 0x2b, 0x0a, 0x17, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x10, 0x0a, 0x03, + 0x69, 0x64, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0xbb, + 0x01, 0x0a, 0x18, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x54, 0x0a, 0x07, 0x72, + 0x65, 0x73, 0x75, 0x6c, 0x74, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x73, + 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, + 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x2e, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x07, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, + 0x73, 0x1a, 0x49, 0x0a, 0x06, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x2f, 0x0a, 0x06, 0x73, + 0x74, 0x61, 0x74, 0x75, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x17, 0x2e, 0x73, 0x70, + 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x53, 0x74, + 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x0e, 0x0a, 0x02, + 0x69, 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x02, 0x69, 0x64, 0x22, 0x5a, 0x0a, 0x1b, + 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, 0x74, + 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x0b, 0x6f, + 0x75, 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, + 0x32, 0x1a, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, + 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x4d, 0x61, 0x73, 0x6b, 0x22, 0x50, 0x0a, 0x1c, 0x47, 0x65, 0x74, 0x41, + 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x30, 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, + 0x69, 0x65, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x16, 0x2e, 0x73, 0x70, 0x69, 0x72, + 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, + 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x22, 0x6d, 0x0a, 0x1c, 0x53, 0x79, + 0x6e, 0x63, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, + 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x12, 0x3b, 0x0a, 0x0b, 0x6f, 0x75, + 0x74, 0x70, 0x75, 0x74, 0x5f, 0x6d, 0x61, 0x73, 0x6b, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1a, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x4d, 0x61, 0x73, 0x6b, 0x52, 0x0a, 0x6f, 0x75, 0x74, + 0x70, 0x75, 0x74, 0x4d, 0x61, 0x73, 0x6b, 0x12, 0x10, 0x0a, 0x03, 0x69, 0x64, 0x73, 0x18, 0x02, + 0x20, 0x03, 0x28, 0x09, 0x52, 0x03, 0x69, 0x64, 0x73, 0x22, 0xb8, 0x01, 0x0a, 0x1d, 0x53, 0x79, + 0x6e, 0x63, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, + 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x51, 0x0a, 0x0f, 0x65, + 0x6e, 0x74, 0x72, 0x79, 0x5f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x01, + 0x20, 0x03, 0x28, 0x0b, 0x32, 0x28, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, + 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, + 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x52, 0x0e, + 0x65, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x30, + 0x0a, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, + 0x16, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x07, 0x65, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x12, 0x12, 0x0a, 0x04, 0x6d, 0x6f, 0x72, 0x65, 0x18, 0x03, 0x20, 0x01, 0x28, 0x08, 0x52, 0x04, + 0x6d, 0x6f, 0x72, 0x65, 0x22, 0x48, 0x0a, 0x0d, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x76, + 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x12, 0x0e, 0x0a, 0x02, 0x69, 0x64, 0x18, 0x01, 0x20, 0x01, 0x28, + 0x09, 0x52, 0x02, 0x69, 0x64, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, + 0x6e, 0x5f, 0x6e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x18, 0x02, 0x20, 0x01, 0x28, 0x03, 0x52, 0x0e, + 0x72, 0x65, 0x76, 0x69, 0x73, 0x69, 0x6f, 0x6e, 0x4e, 0x75, 0x6d, 0x62, 0x65, 0x72, 0x32, 0xc8, + 0x07, 0x0a, 0x05, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x6f, 0x0a, 0x0c, 0x43, 0x6f, 0x75, 0x6e, + 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2e, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, + 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, + 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2f, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, + 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x43, 0x6f, 0x75, 0x6e, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, + 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x6c, 0x0a, 0x0b, 0x4c, 0x69, 0x73, + 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x2d, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, + 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, + 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x2e, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, - 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, - 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x87, 0x01, 0x0a, - 0x14, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, - 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x36, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, + 0x2e, 0x76, 0x31, 0x2e, 0x4c, 0x69, 0x73, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, + 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x4e, 0x0a, 0x08, 0x47, 0x65, 0x74, 0x45, 0x6e, + 0x74, 0x72, 0x79, 0x12, 0x2a, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, + 0x47, 0x65, 0x74, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x16, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x74, 0x79, 0x70, 0x65, + 0x73, 0x2e, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x7b, 0x0a, 0x10, 0x42, 0x61, 0x74, 0x63, 0x68, + 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x32, 0x2e, 0x73, 0x70, + 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, + 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x43, 0x72, 0x65, + 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x33, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, + 0x68, 0x43, 0x72, 0x65, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, + 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x7b, 0x0a, 0x10, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, + 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x32, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, + 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, + 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, 0x64, 0x61, 0x74, 0x65, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x73, + 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, + 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x55, 0x70, + 0x64, 0x61, 0x74, 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, + 0x65, 0x12, 0x7b, 0x0a, 0x10, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, + 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x32, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, - 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, - 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x37, 0x2e, - 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, - 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, - 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8e, 0x01, 0x0a, 0x15, 0x53, 0x79, 0x6e, 0x63, 0x41, + 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x45, 0x6e, 0x74, + 0x72, 0x79, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x33, 0x2e, 0x73, 0x70, 0x69, 0x72, + 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, + 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x42, 0x61, 0x74, 0x63, 0x68, 0x44, 0x65, 0x6c, 0x65, 0x74, + 0x65, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x87, + 0x01, 0x0a, 0x14, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, + 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x12, 0x36, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, + 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, + 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, + 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, + 0x37, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, + 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x47, 0x65, 0x74, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, - 0x12, 0x37, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, + 0x52, 0x65, 0x73, 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x12, 0x8e, 0x01, 0x0a, 0x15, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, - 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x73, 0x70, 0x69, 0x72, - 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, - 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, - 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, 0x70, 0x6f, - 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x49, 0x5a, 0x47, 0x67, 0x69, 0x74, 0x68, 0x75, - 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x2f, 0x73, 0x70, 0x69, - 0x72, 0x65, 0x2d, 0x61, 0x70, 0x69, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, - 0x2f, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, 0x76, 0x65, - 0x72, 0x2f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x6e, 0x74, 0x72, 0x79, - 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, + 0x65, 0x73, 0x12, 0x37, 0x2e, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, + 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x53, + 0x79, 0x6e, 0x63, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, 0x74, + 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x71, 0x75, 0x65, 0x73, 0x74, 0x1a, 0x38, 0x2e, 0x73, 0x70, + 0x69, 0x72, 0x65, 0x2e, 0x61, 0x70, 0x69, 0x2e, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x2e, 0x65, + 0x6e, 0x74, 0x72, 0x79, 0x2e, 0x76, 0x31, 0x2e, 0x53, 0x79, 0x6e, 0x63, 0x41, 0x75, 0x74, 0x68, + 0x6f, 0x72, 0x69, 0x7a, 0x65, 0x64, 0x45, 0x6e, 0x74, 0x72, 0x69, 0x65, 0x73, 0x52, 0x65, 0x73, + 0x70, 0x6f, 0x6e, 0x73, 0x65, 0x28, 0x01, 0x30, 0x01, 0x42, 0x49, 0x5a, 0x47, 0x67, 0x69, 0x74, + 0x68, 0x75, 0x62, 0x2e, 0x63, 0x6f, 0x6d, 0x2f, 0x73, 0x70, 0x69, 0x66, 0x66, 0x65, 0x2f, 0x73, + 0x70, 0x69, 0x72, 0x65, 0x2d, 0x61, 0x70, 0x69, 0x2d, 0x73, 0x64, 0x6b, 0x2f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x2f, 0x73, 0x70, 0x69, 0x72, 0x65, 0x2f, 0x61, 0x70, 0x69, 0x2f, 0x73, 0x65, 0x72, + 0x76, 0x65, 0x72, 0x2f, 0x65, 0x6e, 0x74, 0x72, 0x79, 0x2f, 0x76, 0x31, 0x3b, 0x65, 0x6e, 0x74, + 0x72, 0x79, 0x76, 0x31, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( @@ -1407,7 +1546,7 @@ func file_spire_api_server_entry_v1_entry_proto_rawDescGZIP() []byte { return file_spire_api_server_entry_v1_entry_proto_rawDescData } -var file_spire_api_server_entry_v1_entry_proto_msgTypes = make([]protoimpl.MessageInfo, 20) +var file_spire_api_server_entry_v1_entry_proto_msgTypes = make([]protoimpl.MessageInfo, 21) var file_spire_api_server_entry_v1_entry_proto_goTypes = []interface{}{ (*CountEntriesRequest)(nil), // 0: spire.api.server.entry.v1.CountEntriesRequest (*CountEntriesResponse)(nil), // 1: spire.api.server.entry.v1.CountEntriesResponse @@ -1425,67 +1564,77 @@ var file_spire_api_server_entry_v1_entry_proto_goTypes = []interface{}{ (*SyncAuthorizedEntriesRequest)(nil), // 13: spire.api.server.entry.v1.SyncAuthorizedEntriesRequest (*SyncAuthorizedEntriesResponse)(nil), // 14: spire.api.server.entry.v1.SyncAuthorizedEntriesResponse (*EntryRevision)(nil), // 15: spire.api.server.entry.v1.EntryRevision - (*ListEntriesRequest_Filter)(nil), // 16: spire.api.server.entry.v1.ListEntriesRequest.Filter - (*BatchCreateEntryResponse_Result)(nil), // 17: spire.api.server.entry.v1.BatchCreateEntryResponse.Result - (*BatchUpdateEntryResponse_Result)(nil), // 18: spire.api.server.entry.v1.BatchUpdateEntryResponse.Result - (*BatchDeleteEntryResponse_Result)(nil), // 19: spire.api.server.entry.v1.BatchDeleteEntryResponse.Result - (*types.EntryMask)(nil), // 20: spire.api.types.EntryMask - (*types.Entry)(nil), // 21: spire.api.types.Entry - (*types.SPIFFEID)(nil), // 22: spire.api.types.SPIFFEID - (*types.SelectorMatch)(nil), // 23: spire.api.types.SelectorMatch - (*types.FederatesWithMatch)(nil), // 24: spire.api.types.FederatesWithMatch - (*wrapperspb.StringValue)(nil), // 25: google.protobuf.StringValue - (*types.Status)(nil), // 26: spire.api.types.Status + (*CountEntriesRequest_Filter)(nil), // 16: spire.api.server.entry.v1.CountEntriesRequest.Filter + (*ListEntriesRequest_Filter)(nil), // 17: spire.api.server.entry.v1.ListEntriesRequest.Filter + (*BatchCreateEntryResponse_Result)(nil), // 18: spire.api.server.entry.v1.BatchCreateEntryResponse.Result + (*BatchUpdateEntryResponse_Result)(nil), // 19: spire.api.server.entry.v1.BatchUpdateEntryResponse.Result + (*BatchDeleteEntryResponse_Result)(nil), // 20: spire.api.server.entry.v1.BatchDeleteEntryResponse.Result + (*types.EntryMask)(nil), // 21: spire.api.types.EntryMask + (*types.Entry)(nil), // 22: spire.api.types.Entry + (*types.SPIFFEID)(nil), // 23: spire.api.types.SPIFFEID + (*types.SelectorMatch)(nil), // 24: spire.api.types.SelectorMatch + (*types.FederatesWithMatch)(nil), // 25: spire.api.types.FederatesWithMatch + (*wrapperspb.StringValue)(nil), // 26: google.protobuf.StringValue + (*wrapperspb.BoolValue)(nil), // 27: google.protobuf.BoolValue + (*types.Status)(nil), // 28: spire.api.types.Status } var file_spire_api_server_entry_v1_entry_proto_depIdxs = []int32{ - 16, // 0: spire.api.server.entry.v1.ListEntriesRequest.filter:type_name -> spire.api.server.entry.v1.ListEntriesRequest.Filter - 20, // 1: spire.api.server.entry.v1.ListEntriesRequest.output_mask:type_name -> spire.api.types.EntryMask - 21, // 2: spire.api.server.entry.v1.ListEntriesResponse.entries:type_name -> spire.api.types.Entry - 20, // 3: spire.api.server.entry.v1.GetEntryRequest.output_mask:type_name -> spire.api.types.EntryMask - 21, // 4: spire.api.server.entry.v1.BatchCreateEntryRequest.entries:type_name -> spire.api.types.Entry - 20, // 5: spire.api.server.entry.v1.BatchCreateEntryRequest.output_mask:type_name -> spire.api.types.EntryMask - 17, // 6: spire.api.server.entry.v1.BatchCreateEntryResponse.results:type_name -> spire.api.server.entry.v1.BatchCreateEntryResponse.Result - 21, // 7: spire.api.server.entry.v1.BatchUpdateEntryRequest.entries:type_name -> spire.api.types.Entry - 20, // 8: spire.api.server.entry.v1.BatchUpdateEntryRequest.input_mask:type_name -> spire.api.types.EntryMask - 20, // 9: spire.api.server.entry.v1.BatchUpdateEntryRequest.output_mask:type_name -> spire.api.types.EntryMask - 18, // 10: spire.api.server.entry.v1.BatchUpdateEntryResponse.results:type_name -> spire.api.server.entry.v1.BatchUpdateEntryResponse.Result - 19, // 11: spire.api.server.entry.v1.BatchDeleteEntryResponse.results:type_name -> spire.api.server.entry.v1.BatchDeleteEntryResponse.Result - 20, // 12: spire.api.server.entry.v1.GetAuthorizedEntriesRequest.output_mask:type_name -> spire.api.types.EntryMask - 21, // 13: spire.api.server.entry.v1.GetAuthorizedEntriesResponse.entries:type_name -> spire.api.types.Entry - 20, // 14: spire.api.server.entry.v1.SyncAuthorizedEntriesRequest.output_mask:type_name -> spire.api.types.EntryMask - 15, // 15: spire.api.server.entry.v1.SyncAuthorizedEntriesResponse.entry_revisions:type_name -> spire.api.server.entry.v1.EntryRevision - 21, // 16: spire.api.server.entry.v1.SyncAuthorizedEntriesResponse.entries:type_name -> spire.api.types.Entry - 22, // 17: spire.api.server.entry.v1.ListEntriesRequest.Filter.by_spiffe_id:type_name -> spire.api.types.SPIFFEID - 22, // 18: spire.api.server.entry.v1.ListEntriesRequest.Filter.by_parent_id:type_name -> spire.api.types.SPIFFEID - 23, // 19: spire.api.server.entry.v1.ListEntriesRequest.Filter.by_selectors:type_name -> spire.api.types.SelectorMatch - 24, // 20: spire.api.server.entry.v1.ListEntriesRequest.Filter.by_federates_with:type_name -> spire.api.types.FederatesWithMatch - 25, // 21: spire.api.server.entry.v1.ListEntriesRequest.Filter.by_hint:type_name -> google.protobuf.StringValue - 26, // 22: spire.api.server.entry.v1.BatchCreateEntryResponse.Result.status:type_name -> spire.api.types.Status - 21, // 23: spire.api.server.entry.v1.BatchCreateEntryResponse.Result.entry:type_name -> spire.api.types.Entry - 26, // 24: spire.api.server.entry.v1.BatchUpdateEntryResponse.Result.status:type_name -> spire.api.types.Status - 21, // 25: spire.api.server.entry.v1.BatchUpdateEntryResponse.Result.entry:type_name -> spire.api.types.Entry - 26, // 26: spire.api.server.entry.v1.BatchDeleteEntryResponse.Result.status:type_name -> spire.api.types.Status - 0, // 27: spire.api.server.entry.v1.Entry.CountEntries:input_type -> spire.api.server.entry.v1.CountEntriesRequest - 2, // 28: spire.api.server.entry.v1.Entry.ListEntries:input_type -> spire.api.server.entry.v1.ListEntriesRequest - 4, // 29: spire.api.server.entry.v1.Entry.GetEntry:input_type -> spire.api.server.entry.v1.GetEntryRequest - 5, // 30: spire.api.server.entry.v1.Entry.BatchCreateEntry:input_type -> spire.api.server.entry.v1.BatchCreateEntryRequest - 7, // 31: spire.api.server.entry.v1.Entry.BatchUpdateEntry:input_type -> spire.api.server.entry.v1.BatchUpdateEntryRequest - 9, // 32: spire.api.server.entry.v1.Entry.BatchDeleteEntry:input_type -> spire.api.server.entry.v1.BatchDeleteEntryRequest - 11, // 33: spire.api.server.entry.v1.Entry.GetAuthorizedEntries:input_type -> spire.api.server.entry.v1.GetAuthorizedEntriesRequest - 13, // 34: spire.api.server.entry.v1.Entry.SyncAuthorizedEntries:input_type -> spire.api.server.entry.v1.SyncAuthorizedEntriesRequest - 1, // 35: spire.api.server.entry.v1.Entry.CountEntries:output_type -> spire.api.server.entry.v1.CountEntriesResponse - 3, // 36: spire.api.server.entry.v1.Entry.ListEntries:output_type -> spire.api.server.entry.v1.ListEntriesResponse - 21, // 37: spire.api.server.entry.v1.Entry.GetEntry:output_type -> spire.api.types.Entry - 6, // 38: spire.api.server.entry.v1.Entry.BatchCreateEntry:output_type -> spire.api.server.entry.v1.BatchCreateEntryResponse - 8, // 39: spire.api.server.entry.v1.Entry.BatchUpdateEntry:output_type -> spire.api.server.entry.v1.BatchUpdateEntryResponse - 10, // 40: spire.api.server.entry.v1.Entry.BatchDeleteEntry:output_type -> spire.api.server.entry.v1.BatchDeleteEntryResponse - 12, // 41: spire.api.server.entry.v1.Entry.GetAuthorizedEntries:output_type -> spire.api.server.entry.v1.GetAuthorizedEntriesResponse - 14, // 42: spire.api.server.entry.v1.Entry.SyncAuthorizedEntries:output_type -> spire.api.server.entry.v1.SyncAuthorizedEntriesResponse - 35, // [35:43] is the sub-list for method output_type - 27, // [27:35] is the sub-list for method input_type - 27, // [27:27] is the sub-list for extension type_name - 27, // [27:27] is the sub-list for extension extendee - 0, // [0:27] is the sub-list for field type_name + 16, // 0: spire.api.server.entry.v1.CountEntriesRequest.filter:type_name -> spire.api.server.entry.v1.CountEntriesRequest.Filter + 17, // 1: spire.api.server.entry.v1.ListEntriesRequest.filter:type_name -> spire.api.server.entry.v1.ListEntriesRequest.Filter + 21, // 2: spire.api.server.entry.v1.ListEntriesRequest.output_mask:type_name -> spire.api.types.EntryMask + 22, // 3: spire.api.server.entry.v1.ListEntriesResponse.entries:type_name -> spire.api.types.Entry + 21, // 4: spire.api.server.entry.v1.GetEntryRequest.output_mask:type_name -> spire.api.types.EntryMask + 22, // 5: spire.api.server.entry.v1.BatchCreateEntryRequest.entries:type_name -> spire.api.types.Entry + 21, // 6: spire.api.server.entry.v1.BatchCreateEntryRequest.output_mask:type_name -> spire.api.types.EntryMask + 18, // 7: spire.api.server.entry.v1.BatchCreateEntryResponse.results:type_name -> spire.api.server.entry.v1.BatchCreateEntryResponse.Result + 22, // 8: spire.api.server.entry.v1.BatchUpdateEntryRequest.entries:type_name -> spire.api.types.Entry + 21, // 9: spire.api.server.entry.v1.BatchUpdateEntryRequest.input_mask:type_name -> spire.api.types.EntryMask + 21, // 10: spire.api.server.entry.v1.BatchUpdateEntryRequest.output_mask:type_name -> spire.api.types.EntryMask + 19, // 11: spire.api.server.entry.v1.BatchUpdateEntryResponse.results:type_name -> spire.api.server.entry.v1.BatchUpdateEntryResponse.Result + 20, // 12: spire.api.server.entry.v1.BatchDeleteEntryResponse.results:type_name -> spire.api.server.entry.v1.BatchDeleteEntryResponse.Result + 21, // 13: spire.api.server.entry.v1.GetAuthorizedEntriesRequest.output_mask:type_name -> spire.api.types.EntryMask + 22, // 14: spire.api.server.entry.v1.GetAuthorizedEntriesResponse.entries:type_name -> spire.api.types.Entry + 21, // 15: spire.api.server.entry.v1.SyncAuthorizedEntriesRequest.output_mask:type_name -> spire.api.types.EntryMask + 15, // 16: spire.api.server.entry.v1.SyncAuthorizedEntriesResponse.entry_revisions:type_name -> spire.api.server.entry.v1.EntryRevision + 22, // 17: spire.api.server.entry.v1.SyncAuthorizedEntriesResponse.entries:type_name -> spire.api.types.Entry + 23, // 18: spire.api.server.entry.v1.CountEntriesRequest.Filter.by_spiffe_id:type_name -> spire.api.types.SPIFFEID + 23, // 19: spire.api.server.entry.v1.CountEntriesRequest.Filter.by_parent_id:type_name -> spire.api.types.SPIFFEID + 24, // 20: spire.api.server.entry.v1.CountEntriesRequest.Filter.by_selectors:type_name -> spire.api.types.SelectorMatch + 25, // 21: spire.api.server.entry.v1.CountEntriesRequest.Filter.by_federates_with:type_name -> spire.api.types.FederatesWithMatch + 26, // 22: spire.api.server.entry.v1.CountEntriesRequest.Filter.by_hint:type_name -> google.protobuf.StringValue + 27, // 23: spire.api.server.entry.v1.CountEntriesRequest.Filter.by_downstream:type_name -> google.protobuf.BoolValue + 23, // 24: spire.api.server.entry.v1.ListEntriesRequest.Filter.by_spiffe_id:type_name -> spire.api.types.SPIFFEID + 23, // 25: spire.api.server.entry.v1.ListEntriesRequest.Filter.by_parent_id:type_name -> spire.api.types.SPIFFEID + 24, // 26: spire.api.server.entry.v1.ListEntriesRequest.Filter.by_selectors:type_name -> spire.api.types.SelectorMatch + 25, // 27: spire.api.server.entry.v1.ListEntriesRequest.Filter.by_federates_with:type_name -> spire.api.types.FederatesWithMatch + 26, // 28: spire.api.server.entry.v1.ListEntriesRequest.Filter.by_hint:type_name -> google.protobuf.StringValue + 27, // 29: spire.api.server.entry.v1.ListEntriesRequest.Filter.by_downstream:type_name -> google.protobuf.BoolValue + 28, // 30: spire.api.server.entry.v1.BatchCreateEntryResponse.Result.status:type_name -> spire.api.types.Status + 22, // 31: spire.api.server.entry.v1.BatchCreateEntryResponse.Result.entry:type_name -> spire.api.types.Entry + 28, // 32: spire.api.server.entry.v1.BatchUpdateEntryResponse.Result.status:type_name -> spire.api.types.Status + 22, // 33: spire.api.server.entry.v1.BatchUpdateEntryResponse.Result.entry:type_name -> spire.api.types.Entry + 28, // 34: spire.api.server.entry.v1.BatchDeleteEntryResponse.Result.status:type_name -> spire.api.types.Status + 0, // 35: spire.api.server.entry.v1.Entry.CountEntries:input_type -> spire.api.server.entry.v1.CountEntriesRequest + 2, // 36: spire.api.server.entry.v1.Entry.ListEntries:input_type -> spire.api.server.entry.v1.ListEntriesRequest + 4, // 37: spire.api.server.entry.v1.Entry.GetEntry:input_type -> spire.api.server.entry.v1.GetEntryRequest + 5, // 38: spire.api.server.entry.v1.Entry.BatchCreateEntry:input_type -> spire.api.server.entry.v1.BatchCreateEntryRequest + 7, // 39: spire.api.server.entry.v1.Entry.BatchUpdateEntry:input_type -> spire.api.server.entry.v1.BatchUpdateEntryRequest + 9, // 40: spire.api.server.entry.v1.Entry.BatchDeleteEntry:input_type -> spire.api.server.entry.v1.BatchDeleteEntryRequest + 11, // 41: spire.api.server.entry.v1.Entry.GetAuthorizedEntries:input_type -> spire.api.server.entry.v1.GetAuthorizedEntriesRequest + 13, // 42: spire.api.server.entry.v1.Entry.SyncAuthorizedEntries:input_type -> spire.api.server.entry.v1.SyncAuthorizedEntriesRequest + 1, // 43: spire.api.server.entry.v1.Entry.CountEntries:output_type -> spire.api.server.entry.v1.CountEntriesResponse + 3, // 44: spire.api.server.entry.v1.Entry.ListEntries:output_type -> spire.api.server.entry.v1.ListEntriesResponse + 22, // 45: spire.api.server.entry.v1.Entry.GetEntry:output_type -> spire.api.types.Entry + 6, // 46: spire.api.server.entry.v1.Entry.BatchCreateEntry:output_type -> spire.api.server.entry.v1.BatchCreateEntryResponse + 8, // 47: spire.api.server.entry.v1.Entry.BatchUpdateEntry:output_type -> spire.api.server.entry.v1.BatchUpdateEntryResponse + 10, // 48: spire.api.server.entry.v1.Entry.BatchDeleteEntry:output_type -> spire.api.server.entry.v1.BatchDeleteEntryResponse + 12, // 49: spire.api.server.entry.v1.Entry.GetAuthorizedEntries:output_type -> spire.api.server.entry.v1.GetAuthorizedEntriesResponse + 14, // 50: spire.api.server.entry.v1.Entry.SyncAuthorizedEntries:output_type -> spire.api.server.entry.v1.SyncAuthorizedEntriesResponse + 43, // [43:51] is the sub-list for method output_type + 35, // [35:43] is the sub-list for method input_type + 35, // [35:35] is the sub-list for extension type_name + 35, // [35:35] is the sub-list for extension extendee + 0, // [0:35] is the sub-list for field type_name } func init() { file_spire_api_server_entry_v1_entry_proto_init() } @@ -1687,7 +1836,7 @@ func file_spire_api_server_entry_v1_entry_proto_init() { } } file_spire_api_server_entry_v1_entry_proto_msgTypes[16].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*ListEntriesRequest_Filter); i { + switch v := v.(*CountEntriesRequest_Filter); i { case 0: return &v.state case 1: @@ -1699,7 +1848,7 @@ func file_spire_api_server_entry_v1_entry_proto_init() { } } file_spire_api_server_entry_v1_entry_proto_msgTypes[17].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BatchCreateEntryResponse_Result); i { + switch v := v.(*ListEntriesRequest_Filter); i { case 0: return &v.state case 1: @@ -1711,7 +1860,7 @@ func file_spire_api_server_entry_v1_entry_proto_init() { } } file_spire_api_server_entry_v1_entry_proto_msgTypes[18].Exporter = func(v interface{}, i int) interface{} { - switch v := v.(*BatchUpdateEntryResponse_Result); i { + switch v := v.(*BatchCreateEntryResponse_Result); i { case 0: return &v.state case 1: @@ -1723,6 +1872,18 @@ func file_spire_api_server_entry_v1_entry_proto_init() { } } file_spire_api_server_entry_v1_entry_proto_msgTypes[19].Exporter = func(v interface{}, i int) interface{} { + switch v := v.(*BatchUpdateEntryResponse_Result); i { + case 0: + return &v.state + case 1: + return &v.sizeCache + case 2: + return &v.unknownFields + default: + return nil + } + } + file_spire_api_server_entry_v1_entry_proto_msgTypes[20].Exporter = func(v interface{}, i int) interface{} { switch v := v.(*BatchDeleteEntryResponse_Result); i { case 0: return &v.state @@ -1741,7 +1902,7 @@ func file_spire_api_server_entry_v1_entry_proto_init() { GoPackagePath: reflect.TypeOf(x{}).PkgPath(), RawDescriptor: file_spire_api_server_entry_v1_entry_proto_rawDesc, NumEnums: 0, - NumMessages: 20, + NumMessages: 21, NumExtensions: 0, NumServices: 1, }, diff --git a/vendor/github.com/spiffe/spire-api-sdk/proto/spire/api/server/entry/v1/entry.proto b/vendor/github.com/spiffe/spire-api-sdk/proto/spire/api/server/entry/v1/entry.proto index aab4f13b828..2b56b80b878 100644 --- a/vendor/github.com/spiffe/spire-api-sdk/proto/spire/api/server/entry/v1/entry.proto +++ b/vendor/github.com/spiffe/spire-api-sdk/proto/spire/api/server/entry/v1/entry.proto @@ -68,6 +68,17 @@ service Entry { } message CountEntriesRequest { + message Filter { + spire.api.types.SPIFFEID by_spiffe_id = 1; + spire.api.types.SPIFFEID by_parent_id = 2; + spire.api.types.SelectorMatch by_selectors = 3; + spire.api.types.FederatesWithMatch by_federates_with = 4; + google.protobuf.StringValue by_hint = 5; + google.protobuf.BoolValue by_downstream = 6; + } + + // Filters the entries returned in the response. + Filter filter = 1; } message CountEntriesResponse { @@ -81,6 +92,7 @@ message ListEntriesRequest { spire.api.types.SelectorMatch by_selectors = 3; spire.api.types.FederatesWithMatch by_federates_with = 4; google.protobuf.StringValue by_hint = 5; + google.protobuf.BoolValue by_downstream = 6; } // Filters the entries returned in the response. diff --git a/vendor/modules.txt b/vendor/modules.txt index b16ddca7c4f..ebda72f7f6d 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -891,7 +891,7 @@ github.com/spiffe/go-spiffe/v2/spiffetls/tlsconfig github.com/spiffe/go-spiffe/v2/svid/jwtsvid github.com/spiffe/go-spiffe/v2/svid/x509svid github.com/spiffe/go-spiffe/v2/workloadapi -# github.com/spiffe/spire-api-sdk v1.9.4 +# github.com/spiffe/spire-api-sdk v1.9.6 ## explicit; go 1.12 github.com/spiffe/spire-api-sdk/proto/spire/api/server/entry/v1 github.com/spiffe/spire-api-sdk/proto/spire/api/types From 37ad4b2ee5fd6586fc52c4f58daa1d999181958b Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 May 2024 18:32:21 +0000 Subject: [PATCH 13/23] chore(deps): bump google.golang.org/grpc from 1.63.2 to 1.64.0 Bumps [google.golang.org/grpc](https://github.com/grpc/grpc-go) from 1.63.2 to 1.64.0. - [Release notes](https://github.com/grpc/grpc-go/releases) - [Commits](https://github.com/grpc/grpc-go/compare/v1.63.2...v1.64.0) --- updated-dependencies: - dependency-name: google.golang.org/grpc dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] --- go.mod | 6 +- go.sum | 16 +- .../go/compute/internal/version.go | 2 +- vendor/google.golang.org/grpc/CONTRIBUTING.md | 2 +- vendor/google.golang.org/grpc/MAINTAINERS.md | 1 + vendor/google.golang.org/grpc/Makefile | 7 +- .../grpclb/grpc_lb_v1/load_balancer.pb.go | 2 +- .../grpc_lb_v1/load_balancer_grpc.pb.go | 11 +- .../grpc_binarylog_v1/binarylog.pb.go | 2 +- vendor/google.golang.org/grpc/clientconn.go | 30 +- vendor/google.golang.org/grpc/codegen.sh | 17 -- vendor/google.golang.org/grpc/codes/codes.go | 2 +- .../internal/proto/grpc_gcp/altscontext.pb.go | 2 +- .../internal/proto/grpc_gcp/handshaker.pb.go | 260 +++++++++--------- .../proto/grpc_gcp/handshaker_grpc.pb.go | 65 +---- .../grpc_gcp/transport_security_common.pb.go | 2 +- .../grpc/credentials/credentials.go | 6 +- vendor/google.golang.org/grpc/dialoptions.go | 36 ++- .../grpc/health/grpc_health_v1/health.pb.go | 2 +- .../health/grpc_health_v1/health_grpc.pb.go | 14 +- .../balancer/gracefulswitch/config.go | 1 - .../balancer/gracefulswitch/gracefulswitch.go | 1 - .../grpc/internal/binarylog/method_logger.go | 6 +- .../grpc/internal/envconfig/envconfig.go | 3 - .../grpc/internal/grpcutil/compressor.go | 5 - .../internal/resolver/dns/dns_resolver.go | 32 ++- .../resolver/dns/internal/internal.go | 6 +- .../grpc/internal/transport/controlbuf.go | 33 +-- .../grpc/internal/transport/http2_client.go | 68 +++-- .../grpc/internal/transport/http2_server.go | 12 +- .../grpc/internal/transport/transport.go | 2 +- .../grpc/metadata/metadata.go | 15 + vendor/google.golang.org/grpc/peer/peer.go | 30 ++ .../google.golang.org/grpc/picker_wrapper.go | 3 +- vendor/google.golang.org/grpc/pickfirst.go | 42 ++- vendor/google.golang.org/grpc/regenerate.sh | 6 +- .../grpc/resolver/dns/dns_resolver.go | 12 +- vendor/google.golang.org/grpc/rpc_util.go | 3 +- vendor/google.golang.org/grpc/server.go | 16 +- .../google.golang.org/grpc/service_config.go | 8 +- vendor/google.golang.org/grpc/stats/stats.go | 10 +- vendor/google.golang.org/grpc/stream.go | 1 + .../grpc/stream_interfaces.go | 152 ++++++++++ vendor/google.golang.org/grpc/version.go | 2 +- vendor/google.golang.org/grpc/vet.sh | 195 ------------- vendor/modules.txt | 6 +- 46 files changed, 598 insertions(+), 557 deletions(-) delete mode 100644 vendor/google.golang.org/grpc/codegen.sh create mode 100644 vendor/google.golang.org/grpc/stream_interfaces.go delete mode 100644 vendor/google.golang.org/grpc/vet.sh diff --git a/go.mod b/go.mod index 9ca27598604..ca08798267c 100644 --- a/go.mod +++ b/go.mod @@ -134,7 +134,7 @@ require ( go.opentelemetry.io/otel/exporters/otlp/otlptrace v1.26.0 // indirect go.opentelemetry.io/otel/metric v1.26.0 // indirect go.opentelemetry.io/proto/otlp v1.2.0 // indirect - google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 // indirect + google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 // indirect google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda // indirect gopkg.in/go-jose/go-jose.v2 v2.6.3 // indirect ) @@ -146,7 +146,7 @@ replace ( ) require ( - cloud.google.com/go/compute v1.24.0 // indirect + cloud.google.com/go/compute v1.25.1 // indirect contrib.go.opencensus.io/exporter/ocagent v0.7.1-0.20200907061046-05415f1de66d // indirect contrib.go.opencensus.io/exporter/prometheus v0.4.2 // indirect github.com/Azure/azure-sdk-for-go v68.0.0+incompatible // indirect @@ -241,7 +241,7 @@ require ( golang.org/x/tools v0.17.0 // indirect google.golang.org/api v0.171.0 // indirect google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de // indirect - google.golang.org/grpc v1.63.2 + google.golang.org/grpc v1.64.0 google.golang.org/protobuf v1.34.1 gopkg.in/inf.v0 v0.9.1 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect diff --git a/go.sum b/go.sum index 2e614576bec..e7d9de06029 100644 --- a/go.sum +++ b/go.sum @@ -20,16 +20,16 @@ cloud.google.com/go v0.78.0/go.mod h1:QjdrLG0uq+YwhjoVOLsS1t7TW8fs36kLs4XO5R5ECH cloud.google.com/go v0.79.0/go.mod h1:3bzgcEeQlzbuEAYu4mrWhKqWjmpprinYgKJLgKHnbb8= cloud.google.com/go v0.81.0/go.mod h1:mk/AM35KwGk/Nm2YSeZbxXdrNK3KZOYHmLkOqC2V6E0= cloud.google.com/go v0.83.0/go.mod h1:Z7MJUsANfY0pYPdw0lbnivPx4/vhy/e2FEkSkF7vAVY= -cloud.google.com/go v0.112.0 h1:tpFCD7hpHFlQ8yPwT3x+QeXqc2T6+n6T+hmABHfDUSM= -cloud.google.com/go v0.112.0/go.mod h1:3jEEVwZ/MHU4djK5t5RHuKOA/GbLddgTdVubX1qnPD4= +cloud.google.com/go v0.112.1 h1:uJSeirPke5UNZHIb4SxfZklVSiWWVqW4oXlETwZziwM= +cloud.google.com/go v0.112.1/go.mod h1:+Vbu+Y1UU+I1rjmzeMOb/8RfkKJK2Gyxi1X6jJCZLo4= cloud.google.com/go/bigquery v1.0.1/go.mod h1:i/xbL2UlR5RvWAURpBYZTtm/cXjCha9lbfbpx4poX+o= cloud.google.com/go/bigquery v1.3.0/go.mod h1:PjpwJnslEMmckchkHFfq+HTD2DmtT67aNFKH1/VBDHE= cloud.google.com/go/bigquery v1.4.0/go.mod h1:S8dzgnTigyfTmLBfrtrhyYhwRxG72rYxvftPBK2Dvzc= cloud.google.com/go/bigquery v1.5.0/go.mod h1:snEHRnqQbz117VIFhE8bmtwIDY80NLUZUMb4Nv6dBIg= cloud.google.com/go/bigquery v1.7.0/go.mod h1://okPTzCYNXSlb24MZs83e2Do+h+VXtc4gLoIoXIAPc= cloud.google.com/go/bigquery v1.8.0/go.mod h1:J5hqkt3O0uAFnINi6JXValWIb1v0goeZM77hZzJN/fQ= -cloud.google.com/go/compute v1.24.0 h1:phWcR2eWzRJaL/kOiJwfFsPs4BaKq1j6vnpZrc1YlVg= -cloud.google.com/go/compute v1.24.0/go.mod h1:kw1/T+h/+tK2LJK0wiPPx1intgdAM3j/g3hFDlscY40= +cloud.google.com/go/compute v1.25.1 h1:ZRpHJedLtTpKgr3RV1Fx23NuaAEN1Zfx9hw1u4aJdjU= +cloud.google.com/go/compute v1.25.1/go.mod h1:oopOIR53ly6viBYxaDhBfJwzUAxf1zE//uf3IB011ls= cloud.google.com/go/compute/metadata v0.2.0/go.mod h1:zFmK7XCadkQkj6TtorcaGlCW1hT1fIilQDwofLpJ20k= cloud.google.com/go/compute/metadata v0.2.3 h1:mg4jlk7mCAj6xXp9UJ4fjI9VUI5rubuGBW5aJ7UnBMY= cloud.google.com/go/compute/metadata v0.2.3/go.mod h1:VAV5nSsACxMJvgaAuX6Pk2AawlZn8kiOGuCv6gTkwuA= @@ -1704,8 +1704,8 @@ google.golang.org/genproto v0.0.0-20210513213006-bf773b8c8384/go.mod h1:P3QM42oQ google.golang.org/genproto v0.0.0-20210602131652-f16073e35f0c/go.mod h1:UODoCrxHCcBojKKwX1terBiRUaqAsFqJiF615XL43r0= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de h1:F6qOa9AZTYJXOUEr4jDysRDLrm4PHePlge4v4TGAlxY= google.golang.org/genproto v0.0.0-20240227224415-6ceb2ff114de/go.mod h1:VUhTRKeHn9wwcdrk73nvdC9gF178Tzhmt/qyaFcPLSo= -google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 h1:rIo7ocm2roD9DcFIX67Ym8icoGCKSARAiPljFhh5suQ= -google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2/go.mod h1:O1cOfN1Cy6QEYr7VxtjOyP5AdAuR0aJ/MYZaaof623Y= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 h1:RFiFrvy37/mpSpdySBDrUdipW/dHwsRwh3J3+A9VgT4= +google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237/go.mod h1:Z5Iiy3jtmioajWHDGFk7CeugTyHtPvMHA4UTmUkyalE= google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda h1:LI5DOvAxUPMv/50agcLLoo+AdWc1irS9Rzz4vPuD1V4= google.golang.org/genproto/googleapis/rpc v0.0.0-20240401170217-c3f982113cda/go.mod h1:WtryC6hu0hhx87FDGxWCDptyssuo68sk10vYjF+T9fY= google.golang.org/grpc v0.0.0-20160317175043-d3ddb4469d5a/go.mod h1:yo6s7OP7yaDglbqo1J04qKzAhqBH6lvTonzMVmEdcZw= @@ -1735,8 +1735,8 @@ google.golang.org/grpc v1.37.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQ google.golang.org/grpc v1.37.1/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.38.0/go.mod h1:NREThFqKR1f3iQ6oBuvc5LadQuXVGo9rkm5ZGrQdJfM= google.golang.org/grpc v1.48.0/go.mod h1:vN9eftEi1UMyUsIF80+uQXhHjbXYbm0uXoFCACuMGWk= -google.golang.org/grpc v1.63.2 h1:MUeiw1B2maTVZthpU5xvASfTh3LDbxHd6IJ6QQVU+xM= -google.golang.org/grpc v1.63.2/go.mod h1:WAX/8DgncnokcFUldAxq7GeB5DXHDbMF+lLvDomNkRA= +google.golang.org/grpc v1.64.0 h1:KH3VH9y/MgNQg1dE7b3XfVK0GsPSIzJwdF617gUSbvY= +google.golang.org/grpc v1.64.0/go.mod h1:oxjF8E3FBnjp+/gVFYdWacaLDx9na1aqy9oovLpxQYg= google.golang.org/grpc/cmd/protoc-gen-go-grpc v1.1.0/go.mod h1:6Kw0yEErY5E/yWrBtf03jp27GLLJujG4z/JK95pnjjw= google.golang.org/protobuf v0.0.0-20200109180630-ec00e32a8dfd/go.mod h1:DFci5gLYBciE7Vtevhsrf46CRTquxDuWsQurQQe4oz8= google.golang.org/protobuf v0.0.0-20200221191635-4d8936d0db64/go.mod h1:kwYJMbMJ01Woi6D6+Kah6886xMZcty6N08ah7+eCXa0= diff --git a/vendor/cloud.google.com/go/compute/internal/version.go b/vendor/cloud.google.com/go/compute/internal/version.go index 291a237fe1c..40d1a891605 100644 --- a/vendor/cloud.google.com/go/compute/internal/version.go +++ b/vendor/cloud.google.com/go/compute/internal/version.go @@ -15,4 +15,4 @@ package internal // Version is the current tagged release of the library. -const Version = "1.24.0" +const Version = "1.25.1" diff --git a/vendor/google.golang.org/grpc/CONTRIBUTING.md b/vendor/google.golang.org/grpc/CONTRIBUTING.md index 608aa6e1ac5..0854d298e41 100644 --- a/vendor/google.golang.org/grpc/CONTRIBUTING.md +++ b/vendor/google.golang.org/grpc/CONTRIBUTING.md @@ -66,7 +66,7 @@ How to get your contributions merged smoothly and quickly. - **All tests need to be passing** before your change can be merged. We recommend you **run tests locally** before creating your PR to catch breakages early on. - - `VET_SKIP_PROTO=1 ./vet.sh` to catch vet errors + - `./scripts/vet.sh` to catch vet errors - `go test -cpu 1,4 -timeout 7m ./...` to run the tests - `go test -race -cpu 1,4 -timeout 7m ./...` to run tests in race mode diff --git a/vendor/google.golang.org/grpc/MAINTAINERS.md b/vendor/google.golang.org/grpc/MAINTAINERS.md index c6672c0a3ef..6a8a07781ae 100644 --- a/vendor/google.golang.org/grpc/MAINTAINERS.md +++ b/vendor/google.golang.org/grpc/MAINTAINERS.md @@ -9,6 +9,7 @@ for general contribution guidelines. ## Maintainers (in alphabetical order) +- [atollena](https://github.com/atollena), Datadog, Inc. - [cesarghali](https://github.com/cesarghali), Google LLC - [dfawley](https://github.com/dfawley), Google LLC - [easwars](https://github.com/easwars), Google LLC diff --git a/vendor/google.golang.org/grpc/Makefile b/vendor/google.golang.org/grpc/Makefile index 1f8960922b3..be38384ff6f 100644 --- a/vendor/google.golang.org/grpc/Makefile +++ b/vendor/google.golang.org/grpc/Makefile @@ -30,17 +30,20 @@ testdeps: GO111MODULE=on go get -d -v -t google.golang.org/grpc/... vet: vetdeps - ./vet.sh + ./scripts/vet.sh vetdeps: - ./vet.sh -install + ./scripts/vet.sh -install .PHONY: \ all \ build \ clean \ + deps \ proto \ test \ + testsubmodule \ testrace \ + testdeps \ vet \ vetdeps diff --git a/vendor/google.golang.org/grpc/balancer/grpclb/grpc_lb_v1/load_balancer.pb.go b/vendor/google.golang.org/grpc/balancer/grpclb/grpc_lb_v1/load_balancer.pb.go index 32989b3abb2..bdf93dbfeff 100644 --- a/vendor/google.golang.org/grpc/balancer/grpclb/grpc_lb_v1/load_balancer.pb.go +++ b/vendor/google.golang.org/grpc/balancer/grpclb/grpc_lb_v1/load_balancer.pb.go @@ -19,7 +19,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.33.0 // protoc v4.25.2 // source: grpc/lb/v1/load_balancer.proto diff --git a/vendor/google.golang.org/grpc/balancer/grpclb/grpc_lb_v1/load_balancer_grpc.pb.go b/vendor/google.golang.org/grpc/balancer/grpclb/grpc_lb_v1/load_balancer_grpc.pb.go index d8ec6539d2a..c57857ac0e1 100644 --- a/vendor/google.golang.org/grpc/balancer/grpclb/grpc_lb_v1/load_balancer_grpc.pb.go +++ b/vendor/google.golang.org/grpc/balancer/grpclb/grpc_lb_v1/load_balancer_grpc.pb.go @@ -34,8 +34,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +// Requires gRPC-Go v1.62.0 or later. +const _ = grpc.SupportPackageIsVersion8 const ( LoadBalancer_BalanceLoad_FullMethodName = "/grpc.lb.v1.LoadBalancer/BalanceLoad" @@ -58,11 +58,12 @@ func NewLoadBalancerClient(cc grpc.ClientConnInterface) LoadBalancerClient { } func (c *loadBalancerClient) BalanceLoad(ctx context.Context, opts ...grpc.CallOption) (LoadBalancer_BalanceLoadClient, error) { - stream, err := c.cc.NewStream(ctx, &LoadBalancer_ServiceDesc.Streams[0], LoadBalancer_BalanceLoad_FullMethodName, opts...) + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &LoadBalancer_ServiceDesc.Streams[0], LoadBalancer_BalanceLoad_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &loadBalancerBalanceLoadClient{stream} + x := &loadBalancerBalanceLoadClient{ClientStream: stream} return x, nil } @@ -116,7 +117,7 @@ func RegisterLoadBalancerServer(s grpc.ServiceRegistrar, srv LoadBalancerServer) } func _LoadBalancer_BalanceLoad_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(LoadBalancerServer).BalanceLoad(&loadBalancerBalanceLoadServer{stream}) + return srv.(LoadBalancerServer).BalanceLoad(&loadBalancerBalanceLoadServer{ServerStream: stream}) } type LoadBalancer_BalanceLoadServer interface { diff --git a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go index 856c75dd4e2..1afb1e84ac0 100644 --- a/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go +++ b/vendor/google.golang.org/grpc/binarylog/grpc_binarylog_v1/binarylog.pb.go @@ -18,7 +18,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.33.0 // protoc v4.25.2 // source: grpc/binlog/v1/binarylog.proto diff --git a/vendor/google.golang.org/grpc/clientconn.go b/vendor/google.golang.org/grpc/clientconn.go index c7f2607114a..2359f94b8a4 100644 --- a/vendor/google.golang.org/grpc/clientconn.go +++ b/vendor/google.golang.org/grpc/clientconn.go @@ -37,7 +37,6 @@ import ( "google.golang.org/grpc/internal/channelz" "google.golang.org/grpc/internal/grpcsync" "google.golang.org/grpc/internal/idle" - "google.golang.org/grpc/internal/pretty" iresolver "google.golang.org/grpc/internal/resolver" "google.golang.org/grpc/internal/transport" "google.golang.org/grpc/keepalive" @@ -121,8 +120,9 @@ func (dcs *defaultConfigSelector) SelectConfig(rpcInfo iresolver.RPCInfo) (*ires // https://github.com/grpc/grpc/blob/master/doc/naming.md. e.g. to use dns // resolver, a "dns:///" prefix should be applied to the target. // -// The DialOptions returned by WithBlock, WithTimeout, and -// WithReturnConnectionError are ignored by this function. +// The DialOptions returned by WithBlock, WithTimeout, +// WithReturnConnectionError, and FailOnNonTempDialError are ignored by this +// function. func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error) { cc := &ClientConn{ target: target, @@ -196,6 +196,8 @@ func NewClient(target string, opts ...DialOption) (conn *ClientConn, err error) } // Dial calls DialContext(context.Background(), target, opts...). +// +// Deprecated: use NewClient instead. Will be supported throughout 1.x. func Dial(target string, opts ...DialOption) (*ClientConn, error) { return DialContext(context.Background(), target, opts...) } @@ -209,6 +211,8 @@ func Dial(target string, opts ...DialOption) (*ClientConn, error) { // "passthrough" for backward compatibility. This distinction should not matter // to most users, but could matter to legacy users that specify a custom dialer // and expect it to receive the target string directly. +// +// Deprecated: use NewClient instead. Will be supported throughout 1.x. func DialContext(ctx context.Context, target string, opts ...DialOption) (conn *ClientConn, err error) { // At the end of this method, we kick the channel out of idle, rather than // waiting for the first rpc. @@ -838,6 +842,9 @@ func (cc *ClientConn) newAddrConnLocked(addrs []resolver.Address, opts balancer. stateChan: make(chan struct{}), } ac.ctx, ac.cancel = context.WithCancel(cc.ctx) + // Start with our address set to the first address; this may be updated if + // we connect to different addresses. + ac.channelz.ChannelMetrics.Target.Store(&addrs[0].Addr) channelz.AddTraceEvent(logger, ac.channelz, 0, &channelz.TraceEvent{ Desc: "Subchannel created", @@ -929,10 +936,14 @@ func equalAddresses(a, b []resolver.Address) bool { // updateAddrs updates ac.addrs with the new addresses list and handles active // connections or connection attempts. func (ac *addrConn) updateAddrs(addrs []resolver.Address) { - ac.mu.Lock() - channelz.Infof(logger, ac.channelz, "addrConn: updateAddrs curAddr: %v, addrs: %v", pretty.ToJSON(ac.curAddr), pretty.ToJSON(addrs)) - addrs = copyAddressesWithoutBalancerAttributes(addrs) + limit := len(addrs) + if limit > 5 { + limit = 5 + } + channelz.Infof(logger, ac.channelz, "addrConn: updateAddrs addrs (%d of %d): %v", limit, len(addrs), addrs[:limit]) + + ac.mu.Lock() if equalAddresses(ac.addrs, addrs) { ac.mu.Unlock() return @@ -1167,6 +1178,10 @@ type addrConn struct { // is received, transport is closed, ac has been torn down). transport transport.ClientTransport // The current transport. + // This mutex is used on the RPC path, so its usage should be minimized as + // much as possible. + // TODO: Find a lock-free way to retrieve the transport and state from the + // addrConn. mu sync.Mutex curAddr resolver.Address // The current address. addrs []resolver.Address // All addresses that the resolver resolved to. @@ -1292,6 +1307,7 @@ func (ac *addrConn) resetTransport() { func (ac *addrConn) tryAllAddrs(ctx context.Context, addrs []resolver.Address, connectDeadline time.Time) error { var firstConnErr error for _, addr := range addrs { + ac.channelz.ChannelMetrics.Target.Store(&addr.Addr) if ctx.Err() != nil { return errConnClosing } @@ -1739,7 +1755,7 @@ func encodeAuthority(authority string) string { return false case '!', '$', '&', '\'', '(', ')', '*', '+', ',', ';', '=': // Subdelim characters return false - case ':', '[', ']', '@': // Authority related delimeters + case ':', '[', ']', '@': // Authority related delimiters return false } // Everything else must be escaped. diff --git a/vendor/google.golang.org/grpc/codegen.sh b/vendor/google.golang.org/grpc/codegen.sh deleted file mode 100644 index 4cdc6ba7c09..00000000000 --- a/vendor/google.golang.org/grpc/codegen.sh +++ /dev/null @@ -1,17 +0,0 @@ -#!/usr/bin/env bash - -# This script serves as an example to demonstrate how to generate the gRPC-Go -# interface and the related messages from .proto file. -# -# It assumes the installation of i) Google proto buffer compiler at -# https://github.com/google/protobuf (after v2.6.1) and ii) the Go codegen -# plugin at https://github.com/golang/protobuf (after 2015-02-20). If you have -# not, please install them first. -# -# We recommend running this script at $GOPATH/src. -# -# If this is not what you need, feel free to make your own scripts. Again, this -# script is for demonstration purpose. -# -proto=$1 -protoc --go_out=plugins=grpc:. $proto diff --git a/vendor/google.golang.org/grpc/codes/codes.go b/vendor/google.golang.org/grpc/codes/codes.go index 08476ad1fe1..0b42c302b24 100644 --- a/vendor/google.golang.org/grpc/codes/codes.go +++ b/vendor/google.golang.org/grpc/codes/codes.go @@ -235,7 +235,7 @@ func (c *Code) UnmarshalJSON(b []byte) error { if ci, err := strconv.ParseUint(string(b), 10, 32); err == nil { if ci >= _maxCode { - return fmt.Errorf("invalid code: %q", ci) + return fmt.Errorf("invalid code: %d", ci) } *c = Code(ci) diff --git a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/altscontext.pb.go b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/altscontext.pb.go index ca4d0331543..fe4488a95ed 100644 --- a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/altscontext.pb.go +++ b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/altscontext.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.33.0 // protoc v4.25.2 // source: grpc/gcp/altscontext.proto diff --git a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker.pb.go b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker.pb.go index 93ceaeb2f9c..adbad6b2fa3 100644 --- a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker.pb.go +++ b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.33.0 // protoc v4.25.2 // source: grpc/gcp/handshaker.proto @@ -458,11 +458,11 @@ type ServerHandshakeParameters struct { // (Optional) A list of local identities supported by the server, if // specified. Otherwise, the handshaker chooses a default local identity. LocalIdentities []*Identity `protobuf:"bytes,2,rep,name=local_identities,json=localIdentities,proto3" json:"local_identities,omitempty"` - // (Optional) An access token created by the caller only intended for use in - // ALTS connections. The access token that should be used to authenticate to - // the peer. The access token MUST be strongly bound to the ALTS credentials + // A token created by the caller only intended for use in + // ALTS connections. The token should be used to authenticate to + // the peer. The token MUST be strongly bound to the ALTS credentials // used to establish the connection that the token is sent over. - AccessToken *string `protobuf:"bytes,3,opt,name=access_token,json=accessToken,proto3,oneof" json:"access_token,omitempty"` + Token *string `protobuf:"bytes,3,opt,name=token,proto3,oneof" json:"token,omitempty"` } func (x *ServerHandshakeParameters) Reset() { @@ -511,9 +511,9 @@ func (x *ServerHandshakeParameters) GetLocalIdentities() []*Identity { return nil } -func (x *ServerHandshakeParameters) GetAccessToken() string { - if x != nil && x.AccessToken != nil { - return *x.AccessToken +func (x *ServerHandshakeParameters) GetToken() string { + if x != nil && x.Token != nil { + return *x.Token } return "" } @@ -1110,7 +1110,7 @@ var file_grpc_gcp_handshaker_proto_rawDesc = []byte{ 0x7a, 0x65, 0x18, 0x0a, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x12, 0x21, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x0b, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0b, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xbe, 0x01, 0x0a, 0x19, 0x53, 0x65, + 0x63, 0x65, 0x73, 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xaa, 0x01, 0x0a, 0x19, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x29, 0x0a, 0x10, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, @@ -1119,130 +1119,128 @@ var file_grpc_gcp_handshaker_proto_rawDesc = []byte{ 0x74, 0x69, 0x74, 0x69, 0x65, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0f, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x69, 0x65, - 0x73, 0x12, 0x26, 0x0a, 0x0c, 0x61, 0x63, 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, - 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, 0x48, 0x00, 0x52, 0x0b, 0x61, 0x63, 0x63, 0x65, 0x73, - 0x73, 0x54, 0x6f, 0x6b, 0x65, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x0f, 0x0a, 0x0d, 0x5f, 0x61, 0x63, - 0x63, 0x65, 0x73, 0x73, 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xa5, 0x04, 0x0a, 0x17, 0x53, - 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, - 0x61, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x12, 0x33, 0x0a, 0x15, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, - 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, - 0x01, 0x20, 0x03, 0x28, 0x09, 0x52, 0x14, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x12, 0x6d, 0x0a, 0x14, 0x68, - 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, - 0x65, 0x72, 0x73, 0x18, 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x67, 0x72, 0x70, 0x63, - 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, - 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x2e, 0x48, 0x61, 0x6e, - 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, - 0x45, 0x6e, 0x74, 0x72, 0x79, 0x52, 0x13, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, - 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x6e, - 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x69, 0x6e, - 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x39, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x65, - 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, - 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, - 0x74, 0x52, 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, - 0x12, 0x3b, 0x0a, 0x0f, 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, - 0x69, 0x6e, 0x74, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, - 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0e, 0x72, - 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x40, 0x0a, - 0x0c, 0x72, 0x70, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, - 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x52, - 0x70, 0x63, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, - 0x6e, 0x73, 0x52, 0x0b, 0x72, 0x70, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, - 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x73, 0x69, 0x7a, - 0x65, 0x18, 0x07, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x61, 0x6d, - 0x65, 0x53, 0x69, 0x7a, 0x65, 0x1a, 0x6b, 0x0a, 0x18, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, + 0x73, 0x12, 0x19, 0x0a, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x18, 0x03, 0x20, 0x01, 0x28, 0x09, + 0x48, 0x00, 0x52, 0x05, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x88, 0x01, 0x01, 0x42, 0x08, 0x0a, 0x06, + 0x5f, 0x74, 0x6f, 0x6b, 0x65, 0x6e, 0x22, 0xa5, 0x04, 0x0a, 0x17, 0x53, 0x74, 0x61, 0x72, 0x74, + 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, + 0x65, 0x71, 0x12, 0x33, 0x0a, 0x15, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, + 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x18, 0x01, 0x20, 0x03, 0x28, + 0x09, 0x52, 0x14, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x73, 0x12, 0x6d, 0x0a, 0x14, 0x68, 0x61, 0x6e, 0x64, 0x73, + 0x68, 0x61, 0x6b, 0x65, 0x5f, 0x70, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x18, + 0x02, 0x20, 0x03, 0x28, 0x0b, 0x32, 0x3a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, + 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x61, 0x6e, 0x64, + 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, - 0x79, 0x12, 0x10, 0x0a, 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, - 0x6b, 0x65, 0x79, 0x12, 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, - 0x28, 0x0b, 0x32, 0x23, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x53, 0x65, - 0x72, 0x76, 0x65, 0x72, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x50, 0x61, 0x72, - 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, - 0x38, 0x01, 0x22, 0x62, 0x0a, 0x17, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, - 0x61, 0x6b, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x12, 0x19, 0x0a, - 0x08, 0x69, 0x6e, 0x5f, 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, - 0x07, 0x69, 0x6e, 0x42, 0x79, 0x74, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6e, 0x65, 0x74, 0x77, - 0x6f, 0x72, 0x6b, 0x5f, 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x0d, 0x52, 0x10, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4c, 0x61, 0x74, - 0x65, 0x6e, 0x63, 0x79, 0x4d, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x0d, 0x48, 0x61, 0x6e, 0x64, 0x73, - 0x68, 0x61, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x12, 0x46, 0x0a, 0x0c, 0x63, 0x6c, 0x69, 0x65, - 0x6e, 0x74, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, - 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, - 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, - 0x71, 0x48, 0x00, 0x52, 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, - 0x12, 0x46, 0x0a, 0x0c, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, - 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, - 0x70, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x61, 0x6e, - 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x65, 0x72, - 0x76, 0x65, 0x72, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x37, 0x0a, 0x04, 0x6e, 0x65, 0x78, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, - 0x70, 0x2e, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x4d, - 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x65, 0x78, - 0x74, 0x42, 0x0b, 0x0a, 0x09, 0x72, 0x65, 0x71, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x9a, - 0x03, 0x0a, 0x10, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x73, - 0x75, 0x6c, 0x74, 0x12, 0x31, 0x0a, 0x14, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, - 0x6f, 0x6e, 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, - 0x09, 0x52, 0x13, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, - 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, - 0x5f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, - 0x0e, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, - 0x19, 0x0a, 0x08, 0x6b, 0x65, 0x79, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, - 0x0c, 0x52, 0x07, 0x6b, 0x65, 0x79, 0x44, 0x61, 0x74, 0x61, 0x12, 0x37, 0x0a, 0x0d, 0x70, 0x65, - 0x65, 0x72, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, - 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x49, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0c, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, - 0x69, 0x74, 0x79, 0x12, 0x39, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x65, - 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x72, - 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, - 0x0d, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x2a, - 0x0a, 0x11, 0x6b, 0x65, 0x65, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6f, - 0x70, 0x65, 0x6e, 0x18, 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x6b, 0x65, 0x65, 0x70, 0x43, - 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x49, 0x0a, 0x11, 0x70, 0x65, - 0x65, 0x72, 0x5f, 0x72, 0x70, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, - 0x07, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, - 0x2e, 0x52, 0x70, 0x63, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, - 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0f, 0x70, 0x65, 0x65, 0x72, 0x52, 0x70, 0x63, 0x56, 0x65, 0x72, - 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x72, 0x61, - 0x6d, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6d, - 0x61, 0x78, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x40, 0x0a, 0x10, 0x48, - 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, - 0x12, 0x0a, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, - 0x6f, 0x64, 0x65, 0x12, 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, - 0x20, 0x01, 0x28, 0x09, 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0xbe, 0x01, - 0x0a, 0x0e, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, - 0x12, 0x1d, 0x0a, 0x0a, 0x6f, 0x75, 0x74, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, - 0x20, 0x01, 0x28, 0x0c, 0x52, 0x09, 0x6f, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, - 0x25, 0x0a, 0x0e, 0x62, 0x79, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, - 0x64, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x62, 0x79, 0x74, 0x65, 0x73, 0x43, 0x6f, - 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x12, 0x32, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, - 0x18, 0x03, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, - 0x70, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, - 0x6c, 0x74, 0x52, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x32, 0x0a, 0x06, 0x73, 0x74, - 0x61, 0x74, 0x75, 0x73, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x72, 0x70, + 0x79, 0x52, 0x13, 0x68, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x50, 0x61, 0x72, 0x61, + 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x6e, 0x5f, 0x62, 0x79, 0x74, + 0x65, 0x73, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x69, 0x6e, 0x42, 0x79, 0x74, 0x65, + 0x73, 0x12, 0x39, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, + 0x69, 0x6e, 0x74, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, + 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0d, 0x6c, + 0x6f, 0x63, 0x61, 0x6c, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x3b, 0x0a, 0x0f, + 0x72, 0x65, 0x6d, 0x6f, 0x74, 0x65, 0x5f, 0x65, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x18, + 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, + 0x2e, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x52, 0x0e, 0x72, 0x65, 0x6d, 0x6f, 0x74, + 0x65, 0x45, 0x6e, 0x64, 0x70, 0x6f, 0x69, 0x6e, 0x74, 0x12, 0x40, 0x0a, 0x0c, 0x72, 0x70, 0x63, + 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x06, 0x20, 0x01, 0x28, 0x0b, 0x32, + 0x1d, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x52, 0x70, 0x63, 0x50, 0x72, + 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x52, 0x0b, + 0x72, 0x70, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x6d, + 0x61, 0x78, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x73, 0x69, 0x7a, 0x65, 0x18, 0x07, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x53, 0x69, 0x7a, + 0x65, 0x1a, 0x6b, 0x0a, 0x18, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x50, 0x61, + 0x72, 0x61, 0x6d, 0x65, 0x74, 0x65, 0x72, 0x73, 0x45, 0x6e, 0x74, 0x72, 0x79, 0x12, 0x10, 0x0a, + 0x03, 0x6b, 0x65, 0x79, 0x18, 0x01, 0x20, 0x01, 0x28, 0x05, 0x52, 0x03, 0x6b, 0x65, 0x79, 0x12, + 0x39, 0x0a, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x23, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, + 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x50, 0x61, 0x72, 0x61, 0x6d, 0x65, 0x74, + 0x65, 0x72, 0x73, 0x52, 0x05, 0x76, 0x61, 0x6c, 0x75, 0x65, 0x3a, 0x02, 0x38, 0x01, 0x22, 0x62, + 0x0a, 0x17, 0x4e, 0x65, 0x78, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x4d, + 0x65, 0x73, 0x73, 0x61, 0x67, 0x65, 0x52, 0x65, 0x71, 0x12, 0x19, 0x0a, 0x08, 0x69, 0x6e, 0x5f, + 0x62, 0x79, 0x74, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x69, 0x6e, 0x42, + 0x79, 0x74, 0x65, 0x73, 0x12, 0x2c, 0x0a, 0x12, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x5f, + 0x6c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, 0x5f, 0x6d, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x0d, + 0x52, 0x10, 0x6e, 0x65, 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x4c, 0x61, 0x74, 0x65, 0x6e, 0x63, 0x79, + 0x4d, 0x73, 0x22, 0xe5, 0x01, 0x0a, 0x0d, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, + 0x72, 0x52, 0x65, 0x71, 0x12, 0x46, 0x0a, 0x0c, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x5f, 0x73, + 0x74, 0x61, 0x72, 0x74, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x72, 0x70, + 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x53, 0x74, 0x61, 0x72, 0x74, 0x43, 0x6c, 0x69, 0x65, 0x6e, + 0x74, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, + 0x0b, 0x63, 0x6c, 0x69, 0x65, 0x6e, 0x74, 0x53, 0x74, 0x61, 0x72, 0x74, 0x12, 0x46, 0x0a, 0x0c, + 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x5f, 0x73, 0x74, 0x61, 0x72, 0x74, 0x18, 0x02, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x53, 0x74, + 0x61, 0x72, 0x74, 0x53, 0x65, 0x72, 0x76, 0x65, 0x72, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, + 0x6b, 0x65, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x0b, 0x73, 0x65, 0x72, 0x76, 0x65, 0x72, 0x53, + 0x74, 0x61, 0x72, 0x74, 0x12, 0x37, 0x0a, 0x04, 0x6e, 0x65, 0x78, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x21, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x4e, 0x65, + 0x78, 0x74, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x4d, 0x65, 0x73, 0x73, 0x61, + 0x67, 0x65, 0x52, 0x65, 0x71, 0x48, 0x00, 0x52, 0x04, 0x6e, 0x65, 0x78, 0x74, 0x42, 0x0b, 0x0a, + 0x09, 0x72, 0x65, 0x71, 0x5f, 0x6f, 0x6e, 0x65, 0x6f, 0x66, 0x22, 0x9a, 0x03, 0x0a, 0x10, 0x48, + 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, + 0x31, 0x0a, 0x14, 0x61, 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x5f, 0x70, + 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x01, 0x20, 0x01, 0x28, 0x09, 0x52, 0x13, 0x61, + 0x70, 0x70, 0x6c, 0x69, 0x63, 0x61, 0x74, 0x69, 0x6f, 0x6e, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, + 0x6f, 0x6c, 0x12, 0x27, 0x0a, 0x0f, 0x72, 0x65, 0x63, 0x6f, 0x72, 0x64, 0x5f, 0x70, 0x72, 0x6f, + 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, 0x52, 0x0e, 0x72, 0x65, 0x63, + 0x6f, 0x72, 0x64, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x19, 0x0a, 0x08, 0x6b, + 0x65, 0x79, 0x5f, 0x64, 0x61, 0x74, 0x61, 0x18, 0x03, 0x20, 0x01, 0x28, 0x0c, 0x52, 0x07, 0x6b, + 0x65, 0x79, 0x44, 0x61, 0x74, 0x61, 0x12, 0x37, 0x0a, 0x0d, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x69, + 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, + 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x52, 0x0c, 0x70, 0x65, 0x65, 0x72, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, + 0x39, 0x0a, 0x0e, 0x6c, 0x6f, 0x63, 0x61, 0x6c, 0x5f, 0x69, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, + 0x79, 0x18, 0x05, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x12, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, + 0x63, 0x70, 0x2e, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x52, 0x0d, 0x6c, 0x6f, 0x63, + 0x61, 0x6c, 0x49, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x74, 0x79, 0x12, 0x2a, 0x0a, 0x11, 0x6b, 0x65, + 0x65, 0x70, 0x5f, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x5f, 0x6f, 0x70, 0x65, 0x6e, 0x18, + 0x06, 0x20, 0x01, 0x28, 0x08, 0x52, 0x0f, 0x6b, 0x65, 0x65, 0x70, 0x43, 0x68, 0x61, 0x6e, 0x6e, + 0x65, 0x6c, 0x4f, 0x70, 0x65, 0x6e, 0x12, 0x49, 0x0a, 0x11, 0x70, 0x65, 0x65, 0x72, 0x5f, 0x72, + 0x70, 0x63, 0x5f, 0x76, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, 0x18, 0x07, 0x20, 0x01, 0x28, + 0x0b, 0x32, 0x1d, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x52, 0x70, 0x63, + 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, 0x73, + 0x52, 0x0f, 0x70, 0x65, 0x65, 0x72, 0x52, 0x70, 0x63, 0x56, 0x65, 0x72, 0x73, 0x69, 0x6f, 0x6e, + 0x73, 0x12, 0x24, 0x0a, 0x0e, 0x6d, 0x61, 0x78, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x5f, 0x73, + 0x69, 0x7a, 0x65, 0x18, 0x08, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x0c, 0x6d, 0x61, 0x78, 0x46, 0x72, + 0x61, 0x6d, 0x65, 0x53, 0x69, 0x7a, 0x65, 0x22, 0x40, 0x0a, 0x10, 0x48, 0x61, 0x6e, 0x64, 0x73, + 0x68, 0x61, 0x6b, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x12, 0x12, 0x0a, 0x04, 0x63, + 0x6f, 0x64, 0x65, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0d, 0x52, 0x04, 0x63, 0x6f, 0x64, 0x65, 0x12, + 0x18, 0x0a, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x18, 0x02, 0x20, 0x01, 0x28, 0x09, + 0x52, 0x07, 0x64, 0x65, 0x74, 0x61, 0x69, 0x6c, 0x73, 0x22, 0xbe, 0x01, 0x0a, 0x0e, 0x48, 0x61, + 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x12, 0x1d, 0x0a, 0x0a, + 0x6f, 0x75, 0x74, 0x5f, 0x66, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x18, 0x01, 0x20, 0x01, 0x28, 0x0c, + 0x52, 0x09, 0x6f, 0x75, 0x74, 0x46, 0x72, 0x61, 0x6d, 0x65, 0x73, 0x12, 0x25, 0x0a, 0x0e, 0x62, + 0x79, 0x74, 0x65, 0x73, 0x5f, 0x63, 0x6f, 0x6e, 0x73, 0x75, 0x6d, 0x65, 0x64, 0x18, 0x02, 0x20, + 0x01, 0x28, 0x0d, 0x52, 0x0d, 0x62, 0x79, 0x74, 0x65, 0x73, 0x43, 0x6f, 0x6e, 0x73, 0x75, 0x6d, + 0x65, 0x64, 0x12, 0x32, 0x0a, 0x06, 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x18, 0x03, 0x20, 0x01, + 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x48, 0x61, + 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x52, 0x06, + 0x72, 0x65, 0x73, 0x75, 0x6c, 0x74, 0x12, 0x32, 0x0a, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, + 0x18, 0x04, 0x20, 0x01, 0x28, 0x0b, 0x32, 0x1a, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, + 0x70, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x72, 0x53, 0x74, 0x61, 0x74, + 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2a, 0x4a, 0x0a, 0x11, 0x48, 0x61, + 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, + 0x22, 0x0a, 0x1e, 0x48, 0x41, 0x4e, 0x44, 0x53, 0x48, 0x41, 0x4b, 0x45, 0x5f, 0x50, 0x52, 0x4f, + 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, + 0x44, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x4c, 0x53, 0x10, 0x01, 0x12, 0x08, 0x0a, 0x04, + 0x41, 0x4c, 0x54, 0x53, 0x10, 0x02, 0x2a, 0x45, 0x0a, 0x0f, 0x4e, 0x65, 0x74, 0x77, 0x6f, 0x72, + 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x20, 0x0a, 0x1c, 0x4e, 0x45, 0x54, + 0x57, 0x4f, 0x52, 0x4b, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x55, 0x4e, + 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x54, + 0x43, 0x50, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, 0x02, 0x32, 0x5b, 0x0a, + 0x11, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x72, 0x53, 0x65, 0x72, 0x76, 0x69, + 0x63, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x44, 0x6f, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, + 0x65, 0x12, 0x17, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x48, 0x61, 0x6e, + 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x18, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x72, - 0x53, 0x74, 0x61, 0x74, 0x75, 0x73, 0x52, 0x06, 0x73, 0x74, 0x61, 0x74, 0x75, 0x73, 0x2a, 0x4a, - 0x0a, 0x11, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x50, 0x72, 0x6f, 0x74, 0x6f, - 0x63, 0x6f, 0x6c, 0x12, 0x22, 0x0a, 0x1e, 0x48, 0x41, 0x4e, 0x44, 0x53, 0x48, 0x41, 0x4b, 0x45, - 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, - 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, 0x07, 0x0a, 0x03, 0x54, 0x4c, 0x53, 0x10, 0x01, - 0x12, 0x08, 0x0a, 0x04, 0x41, 0x4c, 0x54, 0x53, 0x10, 0x02, 0x2a, 0x45, 0x0a, 0x0f, 0x4e, 0x65, - 0x74, 0x77, 0x6f, 0x72, 0x6b, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x63, 0x6f, 0x6c, 0x12, 0x20, 0x0a, - 0x1c, 0x4e, 0x45, 0x54, 0x57, 0x4f, 0x52, 0x4b, 0x5f, 0x50, 0x52, 0x4f, 0x54, 0x4f, 0x43, 0x4f, - 0x4c, 0x5f, 0x55, 0x4e, 0x53, 0x50, 0x45, 0x43, 0x49, 0x46, 0x49, 0x45, 0x44, 0x10, 0x00, 0x12, - 0x07, 0x0a, 0x03, 0x54, 0x43, 0x50, 0x10, 0x01, 0x12, 0x07, 0x0a, 0x03, 0x55, 0x44, 0x50, 0x10, - 0x02, 0x32, 0x5b, 0x0a, 0x11, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x72, 0x53, - 0x65, 0x72, 0x76, 0x69, 0x63, 0x65, 0x12, 0x46, 0x0a, 0x0b, 0x44, 0x6f, 0x48, 0x61, 0x6e, 0x64, - 0x73, 0x68, 0x61, 0x6b, 0x65, 0x12, 0x17, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, - 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x71, 0x1a, 0x18, - 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x67, 0x63, 0x70, 0x2e, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, - 0x61, 0x6b, 0x65, 0x72, 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x6b, - 0x0a, 0x15, 0x69, 0x6f, 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x61, 0x6c, 0x74, 0x73, 0x2e, 0x69, - 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x42, 0x0f, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, - 0x6b, 0x65, 0x72, 0x50, 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3f, 0x67, 0x6f, 0x6f, 0x67, - 0x6c, 0x65, 0x2e, 0x67, 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x72, - 0x70, 0x63, 0x2f, 0x63, 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2f, 0x61, - 0x6c, 0x74, 0x73, 0x2f, 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x5f, 0x67, 0x63, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, - 0x74, 0x6f, 0x33, + 0x52, 0x65, 0x73, 0x70, 0x22, 0x00, 0x28, 0x01, 0x30, 0x01, 0x42, 0x6b, 0x0a, 0x15, 0x69, 0x6f, + 0x2e, 0x67, 0x72, 0x70, 0x63, 0x2e, 0x61, 0x6c, 0x74, 0x73, 0x2e, 0x69, 0x6e, 0x74, 0x65, 0x72, + 0x6e, 0x61, 0x6c, 0x42, 0x0f, 0x48, 0x61, 0x6e, 0x64, 0x73, 0x68, 0x61, 0x6b, 0x65, 0x72, 0x50, + 0x72, 0x6f, 0x74, 0x6f, 0x50, 0x01, 0x5a, 0x3f, 0x67, 0x6f, 0x6f, 0x67, 0x6c, 0x65, 0x2e, 0x67, + 0x6f, 0x6c, 0x61, 0x6e, 0x67, 0x2e, 0x6f, 0x72, 0x67, 0x2f, 0x67, 0x72, 0x70, 0x63, 0x2f, 0x63, + 0x72, 0x65, 0x64, 0x65, 0x6e, 0x74, 0x69, 0x61, 0x6c, 0x73, 0x2f, 0x61, 0x6c, 0x74, 0x73, 0x2f, + 0x69, 0x6e, 0x74, 0x65, 0x72, 0x6e, 0x61, 0x6c, 0x2f, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x2f, 0x67, + 0x72, 0x70, 0x63, 0x5f, 0x67, 0x63, 0x70, 0x62, 0x06, 0x70, 0x72, 0x6f, 0x74, 0x6f, 0x33, } var ( diff --git a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go index ba1c46f64b1..d1af55260bd 100644 --- a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go +++ b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/handshaker_grpc.pb.go @@ -32,8 +32,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +// Requires gRPC-Go v1.64.0 or later. +const _ = grpc.SupportPackageIsVersion9 const ( HandshakerService_DoHandshake_FullMethodName = "/grpc.gcp.HandshakerService/DoHandshake" @@ -49,7 +49,7 @@ type HandshakerServiceClient interface { // messages with next. Each time client sends a request, the handshaker // service expects to respond. Client does not have to wait for service's // response before sending next request. - DoHandshake(ctx context.Context, opts ...grpc.CallOption) (HandshakerService_DoHandshakeClient, error) + DoHandshake(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[HandshakerReq, HandshakerResp], error) } type handshakerServiceClient struct { @@ -60,36 +60,18 @@ func NewHandshakerServiceClient(cc grpc.ClientConnInterface) HandshakerServiceCl return &handshakerServiceClient{cc} } -func (c *handshakerServiceClient) DoHandshake(ctx context.Context, opts ...grpc.CallOption) (HandshakerService_DoHandshakeClient, error) { - stream, err := c.cc.NewStream(ctx, &HandshakerService_ServiceDesc.Streams[0], HandshakerService_DoHandshake_FullMethodName, opts...) +func (c *handshakerServiceClient) DoHandshake(ctx context.Context, opts ...grpc.CallOption) (grpc.BidiStreamingClient[HandshakerReq, HandshakerResp], error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &HandshakerService_ServiceDesc.Streams[0], HandshakerService_DoHandshake_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &handshakerServiceDoHandshakeClient{stream} + x := &grpc.GenericClientStream[HandshakerReq, HandshakerResp]{ClientStream: stream} return x, nil } -type HandshakerService_DoHandshakeClient interface { - Send(*HandshakerReq) error - Recv() (*HandshakerResp, error) - grpc.ClientStream -} - -type handshakerServiceDoHandshakeClient struct { - grpc.ClientStream -} - -func (x *handshakerServiceDoHandshakeClient) Send(m *HandshakerReq) error { - return x.ClientStream.SendMsg(m) -} - -func (x *handshakerServiceDoHandshakeClient) Recv() (*HandshakerResp, error) { - m := new(HandshakerResp) - if err := x.ClientStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type HandshakerService_DoHandshakeClient = grpc.BidiStreamingClient[HandshakerReq, HandshakerResp] // HandshakerServiceServer is the server API for HandshakerService service. // All implementations must embed UnimplementedHandshakerServiceServer @@ -101,7 +83,7 @@ type HandshakerServiceServer interface { // messages with next. Each time client sends a request, the handshaker // service expects to respond. Client does not have to wait for service's // response before sending next request. - DoHandshake(HandshakerService_DoHandshakeServer) error + DoHandshake(grpc.BidiStreamingServer[HandshakerReq, HandshakerResp]) error mustEmbedUnimplementedHandshakerServiceServer() } @@ -109,7 +91,7 @@ type HandshakerServiceServer interface { type UnimplementedHandshakerServiceServer struct { } -func (UnimplementedHandshakerServiceServer) DoHandshake(HandshakerService_DoHandshakeServer) error { +func (UnimplementedHandshakerServiceServer) DoHandshake(grpc.BidiStreamingServer[HandshakerReq, HandshakerResp]) error { return status.Errorf(codes.Unimplemented, "method DoHandshake not implemented") } func (UnimplementedHandshakerServiceServer) mustEmbedUnimplementedHandshakerServiceServer() {} @@ -126,30 +108,11 @@ func RegisterHandshakerServiceServer(s grpc.ServiceRegistrar, srv HandshakerServ } func _HandshakerService_DoHandshake_Handler(srv interface{}, stream grpc.ServerStream) error { - return srv.(HandshakerServiceServer).DoHandshake(&handshakerServiceDoHandshakeServer{stream}) + return srv.(HandshakerServiceServer).DoHandshake(&grpc.GenericServerStream[HandshakerReq, HandshakerResp]{ServerStream: stream}) } -type HandshakerService_DoHandshakeServer interface { - Send(*HandshakerResp) error - Recv() (*HandshakerReq, error) - grpc.ServerStream -} - -type handshakerServiceDoHandshakeServer struct { - grpc.ServerStream -} - -func (x *handshakerServiceDoHandshakeServer) Send(m *HandshakerResp) error { - return x.ServerStream.SendMsg(m) -} - -func (x *handshakerServiceDoHandshakeServer) Recv() (*HandshakerReq, error) { - m := new(HandshakerReq) - if err := x.ServerStream.RecvMsg(m); err != nil { - return nil, err - } - return m, nil -} +// This type alias is provided for backwards compatibility with existing code that references the prior non-generic stream type by name. +type HandshakerService_DoHandshakeServer = grpc.BidiStreamingServer[HandshakerReq, HandshakerResp] // HandshakerService_ServiceDesc is the grpc.ServiceDesc for HandshakerService service. // It's only intended for direct use with grpc.RegisterService, diff --git a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/transport_security_common.pb.go b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/transport_security_common.pb.go index 3e53b2b13bc..d65ffe6e7be 100644 --- a/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/transport_security_common.pb.go +++ b/vendor/google.golang.org/grpc/credentials/alts/internal/proto/grpc_gcp/transport_security_common.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.33.0 // protoc v4.25.2 // source: grpc/gcp/transport_security_common.proto diff --git a/vendor/google.golang.org/grpc/credentials/credentials.go b/vendor/google.golang.org/grpc/credentials/credentials.go index f6b55c68b56..665e790bb0f 100644 --- a/vendor/google.golang.org/grpc/credentials/credentials.go +++ b/vendor/google.golang.org/grpc/credentials/credentials.go @@ -30,7 +30,7 @@ import ( "google.golang.org/grpc/attributes" icredentials "google.golang.org/grpc/internal/credentials" - "google.golang.org/protobuf/protoadapt" + "google.golang.org/protobuf/proto" ) // PerRPCCredentials defines the common interface for the credentials which need to @@ -237,7 +237,7 @@ func ClientHandshakeInfoFromContext(ctx context.Context) ClientHandshakeInfo { } // CheckSecurityLevel checks if a connection's security level is greater than or equal to the specified one. -// It returns success if 1) the condition is satisified or 2) AuthInfo struct does not implement GetCommonAuthInfo() method +// It returns success if 1) the condition is satisfied or 2) AuthInfo struct does not implement GetCommonAuthInfo() method // or 3) CommonAuthInfo.SecurityLevel has an invalid zero value. For 2) and 3), it is for the purpose of backward-compatibility. // // This API is experimental. @@ -287,5 +287,5 @@ type ChannelzSecurityValue interface { type OtherChannelzSecurityValue struct { ChannelzSecurityValue Name string - Value protoadapt.MessageV1 + Value proto.Message } diff --git a/vendor/google.golang.org/grpc/dialoptions.go b/vendor/google.golang.org/grpc/dialoptions.go index 402493224e0..00273702b69 100644 --- a/vendor/google.golang.org/grpc/dialoptions.go +++ b/vendor/google.golang.org/grpc/dialoptions.go @@ -300,6 +300,9 @@ func withBackoff(bs internalbackoff.Strategy) DialOption { // // Use of this feature is not recommended. For more information, please see: // https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md +// +// Deprecated: this DialOption is not supported by NewClient. +// Will be supported throughout 1.x. func WithBlock() DialOption { return newFuncDialOption(func(o *dialOptions) { o.block = true @@ -314,10 +317,8 @@ func WithBlock() DialOption { // Use of this feature is not recommended. For more information, please see: // https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md // -// # Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a -// later release. +// Deprecated: this DialOption is not supported by NewClient. +// Will be supported throughout 1.x. func WithReturnConnectionError() DialOption { return newFuncDialOption(func(o *dialOptions) { o.block = true @@ -387,8 +388,8 @@ func WithCredentialsBundle(b credentials.Bundle) DialOption { // WithTimeout returns a DialOption that configures a timeout for dialing a // ClientConn initially. This is valid if and only if WithBlock() is present. // -// Deprecated: use DialContext instead of Dial and context.WithTimeout -// instead. Will be supported throughout 1.x. +// Deprecated: this DialOption is not supported by NewClient. +// Will be supported throughout 1.x. func WithTimeout(d time.Duration) DialOption { return newFuncDialOption(func(o *dialOptions) { o.timeout = d @@ -470,9 +471,8 @@ func withBinaryLogger(bl binarylog.Logger) DialOption { // Use of this feature is not recommended. For more information, please see: // https://github.com/grpc/grpc-go/blob/master/Documentation/anti-patterns.md // -// # Experimental -// -// Notice: This API is EXPERIMENTAL and may be changed or removed in a +// Deprecated: this DialOption is not supported by NewClient. +// This API may be changed or removed in a // later release. func FailOnNonTempDialError(f bool) DialOption { return newFuncDialOption(func(o *dialOptions) { @@ -601,12 +601,22 @@ func WithDisableRetry() DialOption { }) } +// MaxHeaderListSizeDialOption is a DialOption that specifies the maximum +// (uncompressed) size of header list that the client is prepared to accept. +type MaxHeaderListSizeDialOption struct { + MaxHeaderListSize uint32 +} + +func (o MaxHeaderListSizeDialOption) apply(do *dialOptions) { + do.copts.MaxHeaderListSize = &o.MaxHeaderListSize +} + // WithMaxHeaderListSize returns a DialOption that specifies the maximum // (uncompressed) size of header list that the client is prepared to accept. func WithMaxHeaderListSize(s uint32) DialOption { - return newFuncDialOption(func(o *dialOptions) { - o.copts.MaxHeaderListSize = &s - }) + return MaxHeaderListSizeDialOption{ + MaxHeaderListSize: s, + } } // WithDisableHealthCheck disables the LB channel health checking for all @@ -648,7 +658,7 @@ func defaultDialOptions() dialOptions { } } -// withGetMinConnectDeadline specifies the function that clientconn uses to +// withMinConnectDeadline specifies the function that clientconn uses to // get minConnectDeadline. This can be used to make connection attempts happen // faster/slower. // diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go index 5bf880d4190..6a93475a7fb 100644 --- a/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go +++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health.pb.go @@ -17,7 +17,7 @@ // Code generated by protoc-gen-go. DO NOT EDIT. // versions: -// protoc-gen-go v1.32.0 +// protoc-gen-go v1.33.0 // protoc v4.25.2 // source: grpc/health/v1/health.proto diff --git a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go index 4c46c098dc6..8f793e6e89f 100644 --- a/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go +++ b/vendor/google.golang.org/grpc/health/grpc_health_v1/health_grpc.pb.go @@ -32,8 +32,8 @@ import ( // This is a compile-time assertion to ensure that this generated file // is compatible with the grpc package it is being compiled against. -// Requires gRPC-Go v1.32.0 or later. -const _ = grpc.SupportPackageIsVersion7 +// Requires gRPC-Go v1.62.0 or later. +const _ = grpc.SupportPackageIsVersion8 const ( Health_Check_FullMethodName = "/grpc.health.v1.Health/Check" @@ -81,8 +81,9 @@ func NewHealthClient(cc grpc.ClientConnInterface) HealthClient { } func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (*HealthCheckResponse, error) { + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) out := new(HealthCheckResponse) - err := c.cc.Invoke(ctx, Health_Check_FullMethodName, in, out, opts...) + err := c.cc.Invoke(ctx, Health_Check_FullMethodName, in, out, cOpts...) if err != nil { return nil, err } @@ -90,11 +91,12 @@ func (c *healthClient) Check(ctx context.Context, in *HealthCheckRequest, opts . } func (c *healthClient) Watch(ctx context.Context, in *HealthCheckRequest, opts ...grpc.CallOption) (Health_WatchClient, error) { - stream, err := c.cc.NewStream(ctx, &Health_ServiceDesc.Streams[0], Health_Watch_FullMethodName, opts...) + cOpts := append([]grpc.CallOption{grpc.StaticMethod()}, opts...) + stream, err := c.cc.NewStream(ctx, &Health_ServiceDesc.Streams[0], Health_Watch_FullMethodName, cOpts...) if err != nil { return nil, err } - x := &healthWatchClient{stream} + x := &healthWatchClient{ClientStream: stream} if err := x.ClientStream.SendMsg(in); err != nil { return nil, err } @@ -198,7 +200,7 @@ func _Health_Watch_Handler(srv interface{}, stream grpc.ServerStream) error { if err := stream.RecvMsg(m); err != nil { return err } - return srv.(HealthServer).Watch(m, &healthWatchServer{stream}) + return srv.(HealthServer).Watch(m, &healthWatchServer{ServerStream: stream}) } type Health_WatchServer interface { diff --git a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go index 6bf7f87396f..13821a92660 100644 --- a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go +++ b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/config.go @@ -75,7 +75,6 @@ func ParseConfig(cfg json.RawMessage) (serviceconfig.LoadBalancingConfig, error) if err != nil { return nil, fmt.Errorf("error parsing config for policy %q: %v", name, err) } - return &lbConfig{childBuilder: builder, childConfig: cfg}, nil } diff --git a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go index 45d5e50ea9b..73bb4c4ee9a 100644 --- a/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go +++ b/vendor/google.golang.org/grpc/internal/balancer/gracefulswitch/gracefulswitch.go @@ -169,7 +169,6 @@ func (gsb *Balancer) latestBalancer() *balancerWrapper { func (gsb *Balancer) UpdateClientConnState(state balancer.ClientConnState) error { // The resolver data is only relevant to the most recent LB Policy. balToUpdate := gsb.latestBalancer() - gsbCfg, ok := state.BalancerConfig.(*lbConfig) if ok { // Switch to the child in the config unless it is already active. diff --git a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go index e8456a77c25..aa4505a871d 100644 --- a/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go +++ b/vendor/google.golang.org/grpc/internal/binarylog/method_logger.go @@ -65,7 +65,7 @@ type TruncatingMethodLogger struct { callID uint64 idWithinCallGen *callIDGenerator - sink Sink // TODO(blog): make this plugable. + sink Sink // TODO(blog): make this pluggable. } // NewTruncatingMethodLogger returns a new truncating method logger. @@ -80,7 +80,7 @@ func NewTruncatingMethodLogger(h, m uint64) *TruncatingMethodLogger { callID: idGen.next(), idWithinCallGen: &callIDGenerator{}, - sink: DefaultSink, // TODO(blog): make it plugable. + sink: DefaultSink, // TODO(blog): make it pluggable. } } @@ -397,7 +397,7 @@ func metadataKeyOmit(key string) bool { switch key { case "lb-token", ":path", ":authority", "content-encoding", "content-type", "user-agent", "te": return true - case "grpc-trace-bin": // grpc-trace-bin is special because it's visiable to users. + case "grpc-trace-bin": // grpc-trace-bin is special because it's visible to users. return false } return strings.HasPrefix(key, "grpc-") diff --git a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go index 685a3cb41b1..9c915d9e4b2 100644 --- a/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go +++ b/vendor/google.golang.org/grpc/internal/envconfig/envconfig.go @@ -28,9 +28,6 @@ import ( var ( // TXTErrIgnore is set if TXT errors should be ignored ("GRPC_GO_IGNORE_TXT_ERRORS" is not "false"). TXTErrIgnore = boolFromEnv("GRPC_GO_IGNORE_TXT_ERRORS", true) - // AdvertiseCompressors is set if registered compressor should be advertised - // ("GRPC_GO_ADVERTISE_COMPRESSORS" is not "false"). - AdvertiseCompressors = boolFromEnv("GRPC_GO_ADVERTISE_COMPRESSORS", true) // RingHashCap indicates the maximum ring size which defaults to 4096 // entries but may be overridden by setting the environment variable // "GRPC_RING_HASH_CAP". This does not override the default bounds diff --git a/vendor/google.golang.org/grpc/internal/grpcutil/compressor.go b/vendor/google.golang.org/grpc/internal/grpcutil/compressor.go index 9f409096798..e8d866984b3 100644 --- a/vendor/google.golang.org/grpc/internal/grpcutil/compressor.go +++ b/vendor/google.golang.org/grpc/internal/grpcutil/compressor.go @@ -20,8 +20,6 @@ package grpcutil import ( "strings" - - "google.golang.org/grpc/internal/envconfig" ) // RegisteredCompressorNames holds names of the registered compressors. @@ -40,8 +38,5 @@ func IsCompressorNameRegistered(name string) bool { // RegisteredCompressors returns a string of registered compressor names // separated by comma. func RegisteredCompressors() string { - if !envconfig.AdvertiseCompressors { - return "" - } return strings.Join(RegisteredCompressorNames, ",") } diff --git a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go index abab35e250e..f3f52a59a86 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go +++ b/vendor/google.golang.org/grpc/internal/resolver/dns/dns_resolver.go @@ -41,18 +41,24 @@ import ( "google.golang.org/grpc/serviceconfig" ) -// EnableSRVLookups controls whether the DNS resolver attempts to fetch gRPCLB -// addresses from SRV records. Must not be changed after init time. -var EnableSRVLookups = false - -// ResolvingTimeout specifies the maximum duration for a DNS resolution request. -// If the timeout expires before a response is received, the request will be canceled. -// -// It is recommended to set this value at application startup. Avoid modifying this variable -// after initialization as it's not thread-safe for concurrent modification. -var ResolvingTimeout = 30 * time.Second - -var logger = grpclog.Component("dns") +var ( + // EnableSRVLookups controls whether the DNS resolver attempts to fetch gRPCLB + // addresses from SRV records. Must not be changed after init time. + EnableSRVLookups = false + + // MinResolutionInterval is the minimum interval at which re-resolutions are + // allowed. This helps to prevent excessive re-resolution. + MinResolutionInterval = 30 * time.Second + + // ResolvingTimeout specifies the maximum duration for a DNS resolution request. + // If the timeout expires before a response is received, the request will be canceled. + // + // It is recommended to set this value at application startup. Avoid modifying this variable + // after initialization as it's not thread-safe for concurrent modification. + ResolvingTimeout = 30 * time.Second + + logger = grpclog.Component("dns") +) func init() { resolver.Register(NewBuilder()) @@ -208,7 +214,7 @@ func (d *dnsResolver) watcher() { // Success resolving, wait for the next ResolveNow. However, also wait 30 // seconds at the very least to prevent constantly re-resolving. backoffIndex = 1 - waitTime = internal.MinResolutionRate + waitTime = MinResolutionInterval select { case <-d.ctx.Done(): return diff --git a/vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go b/vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go index c7fc557d00c..a7ecaf8d522 100644 --- a/vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go +++ b/vendor/google.golang.org/grpc/internal/resolver/dns/internal/internal.go @@ -28,7 +28,7 @@ import ( // NetResolver groups the methods on net.Resolver that are used by the DNS // resolver implementation. This allows the default net.Resolver instance to be -// overidden from tests. +// overridden from tests. type NetResolver interface { LookupHost(ctx context.Context, host string) (addrs []string, err error) LookupSRV(ctx context.Context, service, proto, name string) (cname string, addrs []*net.SRV, err error) @@ -50,10 +50,6 @@ var ( // The following vars are overridden from tests. var ( - // MinResolutionRate is the minimum rate at which re-resolutions are - // allowed. This helps to prevent excessive re-resolution. - MinResolutionRate = 30 * time.Second - // TimeAfterFunc is used by the DNS resolver to wait for the given duration // to elapse. In non-test code, this is implemented by time.After. In test // code, this can be used to control the amount of time the resolver is diff --git a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go index 83c3829826a..3deadfb4a20 100644 --- a/vendor/google.golang.org/grpc/internal/transport/controlbuf.go +++ b/vendor/google.golang.org/grpc/internal/transport/controlbuf.go @@ -193,7 +193,7 @@ type goAway struct { code http2.ErrCode debugData []byte headsUp bool - closeConn error // if set, loopyWriter will exit, resulting in conn closure + closeConn error // if set, loopyWriter will exit with this error } func (*goAway) isTransportResponseFrame() bool { return false } @@ -336,7 +336,7 @@ func (c *controlBuffer) put(it cbItem) error { return err } -func (c *controlBuffer) executeAndPut(f func(it any) bool, it cbItem) (bool, error) { +func (c *controlBuffer) executeAndPut(f func() bool, it cbItem) (bool, error) { var wakeUp bool c.mu.Lock() if c.err != nil { @@ -344,7 +344,7 @@ func (c *controlBuffer) executeAndPut(f func(it any) bool, it cbItem) (bool, err return false, c.err } if f != nil { - if !f(it) { // f wasn't successful + if !f() { // f wasn't successful c.mu.Unlock() return false, nil } @@ -495,21 +495,22 @@ type loopyWriter struct { ssGoAwayHandler func(*goAway) (bool, error) } -func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimator, conn net.Conn, logger *grpclog.PrefixLogger) *loopyWriter { +func newLoopyWriter(s side, fr *framer, cbuf *controlBuffer, bdpEst *bdpEstimator, conn net.Conn, logger *grpclog.PrefixLogger, goAwayHandler func(*goAway) (bool, error)) *loopyWriter { var buf bytes.Buffer l := &loopyWriter{ - side: s, - cbuf: cbuf, - sendQuota: defaultWindowSize, - oiws: defaultWindowSize, - estdStreams: make(map[uint32]*outStream), - activeStreams: newOutStreamList(), - framer: fr, - hBuf: &buf, - hEnc: hpack.NewEncoder(&buf), - bdpEst: bdpEst, - conn: conn, - logger: logger, + side: s, + cbuf: cbuf, + sendQuota: defaultWindowSize, + oiws: defaultWindowSize, + estdStreams: make(map[uint32]*outStream), + activeStreams: newOutStreamList(), + framer: fr, + hBuf: &buf, + hEnc: hpack.NewEncoder(&buf), + bdpEst: bdpEst, + conn: conn, + logger: logger, + ssGoAwayHandler: goAwayHandler, } return l } diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_client.go b/vendor/google.golang.org/grpc/internal/transport/http2_client.go index deba0c4d9ef..3c63c706986 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_client.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_client.go @@ -114,11 +114,11 @@ type http2Client struct { streamQuota int64 streamsQuotaAvailable chan struct{} waitingStreams uint32 - nextID uint32 registeredCompressors string // Do not access controlBuf with mu held. mu sync.Mutex // guard the following variables + nextID uint32 state transportState activeStreams map[uint32]*Stream // prevGoAway ID records the Last-Stream-ID in the previous GOAway frame. @@ -408,10 +408,10 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts readerErrCh := make(chan error, 1) go t.reader(readerErrCh) defer func() { - if err == nil { - err = <-readerErrCh - } if err != nil { + // writerDone should be closed since the loopy goroutine + // wouldn't have started in the case this function returns an error. + close(t.writerDone) t.Close(err) } }() @@ -458,8 +458,12 @@ func newHTTP2Client(connectCtx, ctx context.Context, addr resolver.Address, opts if err := t.framer.writer.Flush(); err != nil { return nil, err } + // Block until the server preface is received successfully or an error occurs. + if err = <-readerErrCh; err != nil { + return nil, err + } go func() { - t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger) + t.loopy = newLoopyWriter(clientSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger, t.outgoingGoAwayHandler) if err := t.loopy.run(); !isIOError(err) { // Immediately close the connection, as the loopy writer returns // when there are no more active streams and we were draining (the @@ -517,6 +521,17 @@ func (t *http2Client) getPeer() *peer.Peer { } } +// OutgoingGoAwayHandler writes a GOAWAY to the connection. Always returns (false, err) as we want the GoAway +// to be the last frame loopy writes to the transport. +func (t *http2Client) outgoingGoAwayHandler(g *goAway) (bool, error) { + t.mu.Lock() + defer t.mu.Unlock() + if err := t.framer.fr.WriteGoAway(t.nextID-2, http2.ErrCodeNo, g.debugData); err != nil { + return false, err + } + return false, g.closeConn +} + func (t *http2Client) createHeaderFields(ctx context.Context, callHdr *CallHdr) ([]hpack.HeaderField, error) { aud := t.createAudience(callHdr) ri := credentials.RequestInfo{ @@ -781,7 +796,7 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, firstTry := true var ch chan struct{} transportDrainRequired := false - checkForStreamQuota := func(it any) bool { + checkForStreamQuota := func() bool { if t.streamQuota <= 0 { // Can go negative if server decreases it. if firstTry { t.waitingStreams++ @@ -793,23 +808,24 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, t.waitingStreams-- } t.streamQuota-- - h := it.(*headerFrame) - h.streamID = t.nextID - t.nextID += 2 - - // Drain client transport if nextID > MaxStreamID which signals gRPC that - // the connection is closed and a new one must be created for subsequent RPCs. - transportDrainRequired = t.nextID > MaxStreamID - s.id = h.streamID - s.fc = &inFlow{limit: uint32(t.initialWindowSize)} t.mu.Lock() if t.state == draining || t.activeStreams == nil { // Can be niled from Close(). t.mu.Unlock() return false // Don't create a stream if the transport is already closed. } + + hdr.streamID = t.nextID + t.nextID += 2 + // Drain client transport if nextID > MaxStreamID which signals gRPC that + // the connection is closed and a new one must be created for subsequent RPCs. + transportDrainRequired = t.nextID > MaxStreamID + + s.id = hdr.streamID + s.fc = &inFlow{limit: uint32(t.initialWindowSize)} t.activeStreams[s.id] = s t.mu.Unlock() + if t.streamQuota > 0 && t.waitingStreams > 0 { select { case t.streamsQuotaAvailable <- struct{}{}: @@ -819,13 +835,12 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, return true } var hdrListSizeErr error - checkForHeaderListSize := func(it any) bool { + checkForHeaderListSize := func() bool { if t.maxSendHeaderListSize == nil { return true } - hdrFrame := it.(*headerFrame) var sz int64 - for _, f := range hdrFrame.hf { + for _, f := range hdr.hf { if sz += int64(f.Size()); sz > int64(*t.maxSendHeaderListSize) { hdrListSizeErr = status.Errorf(codes.Internal, "header list size to send violates the maximum size (%d bytes) set by server", *t.maxSendHeaderListSize) return false @@ -834,8 +849,8 @@ func (t *http2Client) NewStream(ctx context.Context, callHdr *CallHdr) (*Stream, return true } for { - success, err := t.controlBuf.executeAndPut(func(it any) bool { - return checkForHeaderListSize(it) && checkForStreamQuota(it) + success, err := t.controlBuf.executeAndPut(func() bool { + return checkForHeaderListSize() && checkForStreamQuota() }, hdr) if err != nil { // Connection closed. @@ -946,7 +961,7 @@ func (t *http2Client) closeStream(s *Stream, err error, rst bool, rstCode http2. rst: rst, rstCode: rstCode, } - addBackStreamQuota := func(any) bool { + addBackStreamQuota := func() bool { t.streamQuota++ if t.streamQuota > 0 && t.waitingStreams > 0 { select { @@ -966,7 +981,7 @@ func (t *http2Client) closeStream(s *Stream, err error, rst bool, rstCode http2. // Close kicks off the shutdown process of the transport. This should be called // only once on a transport. Once it is called, the transport should not be -// accessed any more. +// accessed anymore. func (t *http2Client) Close(err error) { t.mu.Lock() // Make sure we only close once. @@ -991,7 +1006,10 @@ func (t *http2Client) Close(err error) { t.kpDormancyCond.Signal() } t.mu.Unlock() - t.controlBuf.finish() + // Per HTTP/2 spec, a GOAWAY frame must be sent before closing the + // connection. See https://httpwg.org/specs/rfc7540.html#GOAWAY. + t.controlBuf.put(&goAway{code: http2.ErrCodeNo, debugData: []byte("client transport shutdown"), closeConn: err}) + <-t.writerDone t.cancel() t.conn.Close() channelz.RemoveEntry(t.channelz.ID) @@ -1099,7 +1117,7 @@ func (t *http2Client) updateWindow(s *Stream, n uint32) { // for the transport and the stream based on the current bdp // estimation. func (t *http2Client) updateFlowControl(n uint32) { - updateIWS := func(any) bool { + updateIWS := func() bool { t.initialWindowSize = int32(n) t.mu.Lock() for _, s := range t.activeStreams { @@ -1252,7 +1270,7 @@ func (t *http2Client) handleSettings(f *http2.SettingsFrame, isFirst bool) { } updateFuncs = append(updateFuncs, updateStreamQuota) } - t.controlBuf.executeAndPut(func(any) bool { + t.controlBuf.executeAndPut(func() bool { for _, f := range updateFuncs { f() } diff --git a/vendor/google.golang.org/grpc/internal/transport/http2_server.go b/vendor/google.golang.org/grpc/internal/transport/http2_server.go index d582e047109..cab0e2d3d44 100644 --- a/vendor/google.golang.org/grpc/internal/transport/http2_server.go +++ b/vendor/google.golang.org/grpc/internal/transport/http2_server.go @@ -330,8 +330,7 @@ func NewServerTransport(conn net.Conn, config *ServerConfig) (_ ServerTransport, t.handleSettings(sf) go func() { - t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger) - t.loopy.ssGoAwayHandler = t.outgoingGoAwayHandler + t.loopy = newLoopyWriter(serverSide, t.framer, t.controlBuf, t.bdpEst, t.conn, t.logger, t.outgoingGoAwayHandler) err := t.loopy.run() close(t.loopyWriterDone) if !isIOError(err) { @@ -860,7 +859,7 @@ func (t *http2Server) handleSettings(f *http2.SettingsFrame) { } return nil }) - t.controlBuf.executeAndPut(func(any) bool { + t.controlBuf.executeAndPut(func() bool { for _, f := range updateFuncs { f() } @@ -1014,12 +1013,13 @@ func (t *http2Server) writeHeaderLocked(s *Stream) error { headerFields = append(headerFields, hpack.HeaderField{Name: "grpc-encoding", Value: s.sendCompress}) } headerFields = appendHeaderFieldsFromMD(headerFields, s.header) - success, err := t.controlBuf.executeAndPut(t.checkForHeaderListSize, &headerFrame{ + hf := &headerFrame{ streamID: s.id, hf: headerFields, endStream: false, onWrite: t.setResetPingStrikes, - }) + } + success, err := t.controlBuf.executeAndPut(func() bool { return t.checkForHeaderListSize(hf) }, hf) if !success { if err != nil { return err @@ -1208,7 +1208,7 @@ func (t *http2Server) keepalive() { continue } if outstandingPing && kpTimeoutLeft <= 0 { - t.Close(fmt.Errorf("keepalive ping not acked within timeout %s", t.kp.Time)) + t.Close(fmt.Errorf("keepalive ping not acked within timeout %s", t.kp.Timeout)) return } if !outstandingPing { diff --git a/vendor/google.golang.org/grpc/internal/transport/transport.go b/vendor/google.golang.org/grpc/internal/transport/transport.go index 0d2a6e47f67..4b39c0ade97 100644 --- a/vendor/google.golang.org/grpc/internal/transport/transport.go +++ b/vendor/google.golang.org/grpc/internal/transport/transport.go @@ -304,7 +304,7 @@ func (s *Stream) isHeaderSent() bool { } // updateHeaderSent updates headerSent and returns true -// if it was alreay set. It is valid only on server-side. +// if it was already set. It is valid only on server-side. func (s *Stream) updateHeaderSent() bool { return atomic.SwapUint32(&s.headerSent, 1) == 1 } diff --git a/vendor/google.golang.org/grpc/metadata/metadata.go b/vendor/google.golang.org/grpc/metadata/metadata.go index 1e9485fd6e2..6c01a9b359c 100644 --- a/vendor/google.golang.org/grpc/metadata/metadata.go +++ b/vendor/google.golang.org/grpc/metadata/metadata.go @@ -90,6 +90,21 @@ func Pairs(kv ...string) MD { return md } +// String implements the Stringer interface for pretty-printing a MD. +// Ordering of the values is non-deterministic as it ranges over a map. +func (md MD) String() string { + var sb strings.Builder + fmt.Fprintf(&sb, "MD{") + for k, v := range md { + if sb.Len() > 3 { + fmt.Fprintf(&sb, ", ") + } + fmt.Fprintf(&sb, "%s=[%s]", k, strings.Join(v, ", ")) + } + fmt.Fprintf(&sb, "}") + return sb.String() +} + // Len returns the number of items in md. func (md MD) Len() int { return len(md) diff --git a/vendor/google.golang.org/grpc/peer/peer.go b/vendor/google.golang.org/grpc/peer/peer.go index a821ff9b2b7..499a49c8c1c 100644 --- a/vendor/google.golang.org/grpc/peer/peer.go +++ b/vendor/google.golang.org/grpc/peer/peer.go @@ -22,7 +22,9 @@ package peer import ( "context" + "fmt" "net" + "strings" "google.golang.org/grpc/credentials" ) @@ -39,6 +41,34 @@ type Peer struct { AuthInfo credentials.AuthInfo } +// String ensures the Peer types implements the Stringer interface in order to +// allow to print a context with a peerKey value effectively. +func (p *Peer) String() string { + if p == nil { + return "Peer" + } + sb := &strings.Builder{} + sb.WriteString("Peer{") + if p.Addr != nil { + fmt.Fprintf(sb, "Addr: '%s', ", p.Addr.String()) + } else { + fmt.Fprintf(sb, "Addr: , ") + } + if p.LocalAddr != nil { + fmt.Fprintf(sb, "LocalAddr: '%s', ", p.LocalAddr.String()) + } else { + fmt.Fprintf(sb, "LocalAddr: , ") + } + if p.AuthInfo != nil { + fmt.Fprintf(sb, "AuthInfo: '%s'", p.AuthInfo.AuthType()) + } else { + fmt.Fprintf(sb, "AuthInfo: ") + } + sb.WriteString("}") + + return sb.String() +} + type peerKey struct{} // NewContext creates a new context with peer information attached. diff --git a/vendor/google.golang.org/grpc/picker_wrapper.go b/vendor/google.golang.org/grpc/picker_wrapper.go index bf56faa76d3..56e8aba783f 100644 --- a/vendor/google.golang.org/grpc/picker_wrapper.go +++ b/vendor/google.golang.org/grpc/picker_wrapper.go @@ -20,6 +20,7 @@ package grpc import ( "context" + "fmt" "io" "sync" @@ -117,7 +118,7 @@ func (pw *pickerWrapper) pick(ctx context.Context, failfast bool, info balancer. if lastPickErr != nil { errStr = "latest balancer error: " + lastPickErr.Error() } else { - errStr = ctx.Err().Error() + errStr = fmt.Sprintf("received context error while waiting for new LB policy update: %s", ctx.Err().Error()) } switch ctx.Err() { case context.DeadlineExceeded: diff --git a/vendor/google.golang.org/grpc/pickfirst.go b/vendor/google.golang.org/grpc/pickfirst.go index e3ea42ba962..8853626614e 100644 --- a/vendor/google.golang.org/grpc/pickfirst.go +++ b/vendor/google.golang.org/grpc/pickfirst.go @@ -54,7 +54,7 @@ type pfConfig struct { serviceconfig.LoadBalancingConfig `json:"-"` // If set to true, instructs the LB policy to shuffle the order of the list - // of addresses received from the name resolver before attempting to + // of endpoints received from the name resolver before attempting to // connect to them. ShuffleAddressList bool `json:"shuffleAddressList"` } @@ -94,8 +94,7 @@ func (b *pickfirstBalancer) ResolverError(err error) { } func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState) error { - addrs := state.ResolverState.Addresses - if len(addrs) == 0 { + if len(state.ResolverState.Addresses) == 0 && len(state.ResolverState.Endpoints) == 0 { // The resolver reported an empty address list. Treat it like an error by // calling b.ResolverError. if b.subConn != nil { @@ -107,22 +106,49 @@ func (b *pickfirstBalancer) UpdateClientConnState(state balancer.ClientConnState b.ResolverError(errors.New("produced zero addresses")) return balancer.ErrBadResolverState } - // We don't have to guard this block with the env var because ParseConfig // already does so. cfg, ok := state.BalancerConfig.(pfConfig) if state.BalancerConfig != nil && !ok { return fmt.Errorf("pickfirst: received illegal BalancerConfig (type %T): %v", state.BalancerConfig, state.BalancerConfig) } - if cfg.ShuffleAddressList { - addrs = append([]resolver.Address{}, addrs...) - grpcrand.Shuffle(len(addrs), func(i, j int) { addrs[i], addrs[j] = addrs[j], addrs[i] }) - } if b.logger.V(2) { b.logger.Infof("Received new config %s, resolver state %s", pretty.ToJSON(cfg), pretty.ToJSON(state.ResolverState)) } + var addrs []resolver.Address + if endpoints := state.ResolverState.Endpoints; len(endpoints) != 0 { + // Perform the optional shuffling described in gRFC A62. The shuffling will + // change the order of endpoints but not touch the order of the addresses + // within each endpoint. - A61 + if cfg.ShuffleAddressList { + endpoints = append([]resolver.Endpoint{}, endpoints...) + grpcrand.Shuffle(len(endpoints), func(i, j int) { endpoints[i], endpoints[j] = endpoints[j], endpoints[i] }) + } + + // "Flatten the list by concatenating the ordered list of addresses for each + // of the endpoints, in order." - A61 + for _, endpoint := range endpoints { + // "In the flattened list, interleave addresses from the two address + // families, as per RFC-8304 section 4." - A61 + // TODO: support the above language. + addrs = append(addrs, endpoint.Addresses...) + } + } else { + // Endpoints not set, process addresses until we migrate resolver + // emissions fully to Endpoints. The top channel does wrap emitted + // addresses with endpoints, however some balancers such as weighted + // target do not forwarrd the corresponding correct endpoints down/split + // endpoints properly. Once all balancers correctly forward endpoints + // down, can delete this else conditional. + addrs = state.ResolverState.Addresses + if cfg.ShuffleAddressList { + addrs = append([]resolver.Address{}, addrs...) + grpcrand.Shuffle(len(addrs), func(i, j int) { addrs[i], addrs[j] = addrs[j], addrs[i] }) + } + } + if b.subConn != nil { b.cc.UpdateAddresses(b.subConn, addrs) return nil diff --git a/vendor/google.golang.org/grpc/regenerate.sh b/vendor/google.golang.org/grpc/regenerate.sh index a6f26c8ab0f..3edca296c22 100644 --- a/vendor/google.golang.org/grpc/regenerate.sh +++ b/vendor/google.golang.org/grpc/regenerate.sh @@ -63,7 +63,7 @@ LEGACY_SOURCES=( # Generates only the new gRPC Service symbols SOURCES=( - $(git ls-files --exclude-standard --cached --others "*.proto" | grep -v '^\(profiling/proto/service.proto\|reflection/grpc_reflection_v1alpha/reflection.proto\)$') + $(git ls-files --exclude-standard --cached --others "*.proto" | grep -v '^profiling/proto/service.proto$') ${WORKDIR}/grpc-proto/grpc/gcp/altscontext.proto ${WORKDIR}/grpc-proto/grpc/gcp/handshaker.proto ${WORKDIR}/grpc-proto/grpc/gcp/transport_security_common.proto @@ -93,7 +93,7 @@ Mgrpc/testing/empty.proto=google.golang.org/grpc/interop/grpc_testing for src in ${SOURCES[@]}; do echo "protoc ${src}" - protoc --go_out=${OPTS}:${WORKDIR}/out --go-grpc_out=${OPTS}:${WORKDIR}/out \ + protoc --go_out=${OPTS}:${WORKDIR}/out --go-grpc_out=${OPTS},use_generic_streams_experimental=true:${WORKDIR}/out \ -I"." \ -I${WORKDIR}/grpc-proto \ -I${WORKDIR}/googleapis \ @@ -118,6 +118,6 @@ mv ${WORKDIR}/out/google.golang.org/grpc/lookup/grpc_lookup_v1/* ${WORKDIR}/out/ # grpc_testing_not_regenerate/*.pb.go are not re-generated, # see grpc_testing_not_regenerate/README.md for details. -rm ${WORKDIR}/out/google.golang.org/grpc/reflection/grpc_testing_not_regenerate/*.pb.go +rm ${WORKDIR}/out/google.golang.org/grpc/reflection/test/grpc_testing_not_regenerate/*.pb.go cp -R ${WORKDIR}/out/google.golang.org/grpc/* . diff --git a/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go b/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go index b54a3a3225d..ef3d6ed6c43 100644 --- a/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go +++ b/vendor/google.golang.org/grpc/resolver/dns/dns_resolver.go @@ -18,9 +18,6 @@ // Package dns implements a dns resolver to be installed as the default resolver // in grpc. -// -// Deprecated: this package is imported by grpc and should not need to be -// imported directly by users. package dns import ( @@ -52,3 +49,12 @@ func SetResolvingTimeout(timeout time.Duration) { func NewBuilder() resolver.Builder { return dns.NewBuilder() } + +// SetMinResolutionInterval sets the default minimum interval at which DNS +// re-resolutions are allowed. This helps to prevent excessive re-resolution. +// +// It must be called only at application startup, before any gRPC calls are +// made. Modifying this value after initialization is not thread-safe. +func SetMinResolutionInterval(d time.Duration) { + dns.MinResolutionInterval = d +} diff --git a/vendor/google.golang.org/grpc/rpc_util.go b/vendor/google.golang.org/grpc/rpc_util.go index 998e251ddc4..fdd49e6e915 100644 --- a/vendor/google.golang.org/grpc/rpc_util.go +++ b/vendor/google.golang.org/grpc/rpc_util.go @@ -964,7 +964,7 @@ func setCallInfoCodec(c *callInfo) error { // The SupportPackageIsVersion variables are referenced from generated protocol // buffer files to ensure compatibility with the gRPC version used. The latest -// support package version is 7. +// support package version is 9. // // Older versions are kept for compatibility. // @@ -976,6 +976,7 @@ const ( SupportPackageIsVersion6 = true SupportPackageIsVersion7 = true SupportPackageIsVersion8 = true + SupportPackageIsVersion9 = true ) const grpcUA = "grpc-go/" + Version diff --git a/vendor/google.golang.org/grpc/server.go b/vendor/google.golang.org/grpc/server.go index fd4558daa52..89f8e4792bf 100644 --- a/vendor/google.golang.org/grpc/server.go +++ b/vendor/google.golang.org/grpc/server.go @@ -527,12 +527,22 @@ func ConnectionTimeout(d time.Duration) ServerOption { }) } +// MaxHeaderListSizeServerOption is a ServerOption that sets the max +// (uncompressed) size of header list that the server is prepared to accept. +type MaxHeaderListSizeServerOption struct { + MaxHeaderListSize uint32 +} + +func (o MaxHeaderListSizeServerOption) apply(so *serverOptions) { + so.maxHeaderListSize = &o.MaxHeaderListSize +} + // MaxHeaderListSize returns a ServerOption that sets the max (uncompressed) size // of header list that the server is prepared to accept. func MaxHeaderListSize(s uint32) ServerOption { - return newFuncServerOption(func(o *serverOptions) { - o.maxHeaderListSize = &s - }) + return MaxHeaderListSizeServerOption{ + MaxHeaderListSize: s, + } } // HeaderTableSize returns a ServerOption that sets the size of dynamic diff --git a/vendor/google.golang.org/grpc/service_config.go b/vendor/google.golang.org/grpc/service_config.go index 2b35c5d2130..9da8fc8027d 100644 --- a/vendor/google.golang.org/grpc/service_config.go +++ b/vendor/google.golang.org/grpc/service_config.go @@ -172,7 +172,7 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult { var rsc jsonSC err := json.Unmarshal([]byte(js), &rsc) if err != nil { - logger.Warningf("grpc: unmarshaling service config %s: %v", js, err) + logger.Warningf("grpc: unmarshalling service config %s: %v", js, err) return &serviceconfig.ParseResult{Err: err} } sc := ServiceConfig{ @@ -219,7 +219,7 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult { Timeout: (*time.Duration)(m.Timeout), } if mc.RetryPolicy, err = convertRetryPolicy(m.RetryPolicy); err != nil { - logger.Warningf("grpc: unmarshaling service config %s: %v", js, err) + logger.Warningf("grpc: unmarshalling service config %s: %v", js, err) return &serviceconfig.ParseResult{Err: err} } if m.MaxRequestMessageBytes != nil { @@ -239,13 +239,13 @@ func parseServiceConfig(js string) *serviceconfig.ParseResult { for i, n := range *m.Name { path, err := n.generatePath() if err != nil { - logger.Warningf("grpc: error unmarshaling service config %s due to methodConfig[%d]: %v", js, i, err) + logger.Warningf("grpc: error unmarshalling service config %s due to methodConfig[%d]: %v", js, i, err) return &serviceconfig.ParseResult{Err: err} } if _, ok := paths[path]; ok { err = errDuplicatedName - logger.Warningf("grpc: error unmarshaling service config %s due to methodConfig[%d]: %v", js, i, err) + logger.Warningf("grpc: error unmarshalling service config %s due to methodConfig[%d]: %v", js, i, err) return &serviceconfig.ParseResult{Err: err} } paths[path] = struct{}{} diff --git a/vendor/google.golang.org/grpc/stats/stats.go b/vendor/google.golang.org/grpc/stats/stats.go index 4ab70e2d462..fdb0bd65182 100644 --- a/vendor/google.golang.org/grpc/stats/stats.go +++ b/vendor/google.golang.org/grpc/stats/stats.go @@ -73,9 +73,12 @@ func (*PickerUpdated) isRPCStats() {} type InPayload struct { // Client is true if this InPayload is from client side. Client bool - // Payload is the payload with original type. + // Payload is the payload with original type. This may be modified after + // the call to HandleRPC which provides the InPayload returns and must be + // copied if needed later. Payload any // Data is the serialized message payload. + // Deprecated: Data will be removed in the next release. Data []byte // Length is the size of the uncompressed payload data. Does not include any @@ -143,9 +146,12 @@ func (s *InTrailer) isRPCStats() {} type OutPayload struct { // Client is true if this OutPayload is from client side. Client bool - // Payload is the payload with original type. + // Payload is the payload with original type. This may be modified after + // the call to HandleRPC which provides the OutPayload returns and must be + // copied if needed later. Payload any // Data is the serialized message payload. + // Deprecated: Data will be removed in the next release. Data []byte // Length is the size of the uncompressed payload data. Does not include any // framing (gRPC or HTTP/2). diff --git a/vendor/google.golang.org/grpc/stream.go b/vendor/google.golang.org/grpc/stream.go index d939ffc6348..b54563e81cd 100644 --- a/vendor/google.golang.org/grpc/stream.go +++ b/vendor/google.golang.org/grpc/stream.go @@ -516,6 +516,7 @@ func (a *csAttempt) newStream() error { return toRPCErr(nse.Err) } a.s = s + a.ctx = s.Context() a.p = &parser{r: s, recvBufferPool: a.cs.cc.dopts.recvBufferPool} return nil } diff --git a/vendor/google.golang.org/grpc/stream_interfaces.go b/vendor/google.golang.org/grpc/stream_interfaces.go new file mode 100644 index 00000000000..8b813529c0c --- /dev/null +++ b/vendor/google.golang.org/grpc/stream_interfaces.go @@ -0,0 +1,152 @@ +/* + * + * Copyright 2024 gRPC authors. + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + * + */ + +package grpc + +// ServerStreamingClient represents the client side of a server-streaming (one +// request, many responses) RPC. It is generic over the type of the response +// message. It is used in generated code. +type ServerStreamingClient[Res any] interface { + Recv() (*Res, error) + ClientStream +} + +// ServerStreamingServer represents the server side of a server-streaming (one +// request, many responses) RPC. It is generic over the type of the response +// message. It is used in generated code. +type ServerStreamingServer[Res any] interface { + Send(*Res) error + ServerStream +} + +// ClientStreamingClient represents the client side of a client-streaming (many +// requests, one response) RPC. It is generic over both the type of the request +// message stream and the type of the unary response message. It is used in +// generated code. +type ClientStreamingClient[Req any, Res any] interface { + Send(*Req) error + CloseAndRecv() (*Res, error) + ClientStream +} + +// ClientStreamingServer represents the server side of a client-streaming (many +// requests, one response) RPC. It is generic over both the type of the request +// message stream and the type of the unary response message. It is used in +// generated code. +type ClientStreamingServer[Req any, Res any] interface { + Recv() (*Req, error) + SendAndClose(*Res) error + ServerStream +} + +// BidiStreamingClient represents the client side of a bidirectional-streaming +// (many requests, many responses) RPC. It is generic over both the type of the +// request message stream and the type of the response message stream. It is +// used in generated code. +type BidiStreamingClient[Req any, Res any] interface { + Send(*Req) error + Recv() (*Res, error) + ClientStream +} + +// BidiStreamingServer represents the server side of a bidirectional-streaming +// (many requests, many responses) RPC. It is generic over both the type of the +// request message stream and the type of the response message stream. It is +// used in generated code. +type BidiStreamingServer[Req any, Res any] interface { + Recv() (*Req, error) + Send(*Res) error + ServerStream +} + +// GenericClientStream implements the ServerStreamingClient, ClientStreamingClient, +// and BidiStreamingClient interfaces. It is used in generated code. +type GenericClientStream[Req any, Res any] struct { + ClientStream +} + +var _ ServerStreamingClient[string] = (*GenericClientStream[int, string])(nil) +var _ ClientStreamingClient[int, string] = (*GenericClientStream[int, string])(nil) +var _ BidiStreamingClient[int, string] = (*GenericClientStream[int, string])(nil) + +// Send pushes one message into the stream of requests to be consumed by the +// server. The type of message which can be sent is determined by the Req type +// parameter of the GenericClientStream receiver. +func (x *GenericClientStream[Req, Res]) Send(m *Req) error { + return x.ClientStream.SendMsg(m) +} + +// Recv reads one message from the stream of responses generated by the server. +// The type of the message returned is determined by the Res type parameter +// of the GenericClientStream receiver. +func (x *GenericClientStream[Req, Res]) Recv() (*Res, error) { + m := new(Res) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// CloseAndRecv closes the sending side of the stream, then receives the unary +// response from the server. The type of message which it returns is determined +// by the Res type parameter of the GenericClientStream receiver. +func (x *GenericClientStream[Req, Res]) CloseAndRecv() (*Res, error) { + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + m := new(Res) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +// GenericServerStream implements the ServerStreamingServer, ClientStreamingServer, +// and BidiStreamingServer interfaces. It is used in generated code. +type GenericServerStream[Req any, Res any] struct { + ServerStream +} + +var _ ServerStreamingServer[string] = (*GenericServerStream[int, string])(nil) +var _ ClientStreamingServer[int, string] = (*GenericServerStream[int, string])(nil) +var _ BidiStreamingServer[int, string] = (*GenericServerStream[int, string])(nil) + +// Send pushes one message into the stream of responses to be consumed by the +// client. The type of message which can be sent is determined by the Res +// type parameter of the serverStreamServer receiver. +func (x *GenericServerStream[Req, Res]) Send(m *Res) error { + return x.ServerStream.SendMsg(m) +} + +// SendAndClose pushes the unary response to the client. The type of message +// which can be sent is determined by the Res type parameter of the +// clientStreamServer receiver. +func (x *GenericServerStream[Req, Res]) SendAndClose(m *Res) error { + return x.ServerStream.SendMsg(m) +} + +// Recv reads one message from the stream of requests generated by the client. +// The type of the message returned is determined by the Req type parameter +// of the clientStreamServer receiver. +func (x *GenericServerStream[Req, Res]) Recv() (*Req, error) { + m := new(Req) + if err := x.ServerStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} diff --git a/vendor/google.golang.org/grpc/version.go b/vendor/google.golang.org/grpc/version.go index 2556f758386..e1806e76000 100644 --- a/vendor/google.golang.org/grpc/version.go +++ b/vendor/google.golang.org/grpc/version.go @@ -19,4 +19,4 @@ package grpc // Version is the current grpc version. -const Version = "1.63.2" +const Version = "1.64.0" diff --git a/vendor/google.golang.org/grpc/vet.sh b/vendor/google.golang.org/grpc/vet.sh deleted file mode 100644 index 7e6b92e491a..00000000000 --- a/vendor/google.golang.org/grpc/vet.sh +++ /dev/null @@ -1,195 +0,0 @@ -#!/bin/bash - -set -ex # Exit on error; debugging enabled. -set -o pipefail # Fail a pipe if any sub-command fails. - -# not makes sure the command passed to it does not exit with a return code of 0. -not() { - # This is required instead of the earlier (! $COMMAND) because subshells and - # pipefail don't work the same on Darwin as in Linux. - ! "$@" -} - -die() { - echo "$@" >&2 - exit 1 -} - -fail_on_output() { - tee /dev/stderr | not read -} - -# Check to make sure it's safe to modify the user's git repo. -git status --porcelain | fail_on_output - -# Undo any edits made by this script. -cleanup() { - git reset --hard HEAD -} -trap cleanup EXIT - -PATH="${HOME}/go/bin:${GOROOT}/bin:${PATH}" -go version - -if [[ "$1" = "-install" ]]; then - # Install the pinned versions as defined in module tools. - pushd ./test/tools - go install \ - golang.org/x/tools/cmd/goimports \ - honnef.co/go/tools/cmd/staticcheck \ - github.com/client9/misspell/cmd/misspell - popd - if [[ -z "${VET_SKIP_PROTO}" ]]; then - if [[ "${GITHUB_ACTIONS}" = "true" ]]; then - PROTOBUF_VERSION=25.2 # a.k.a. v4.22.0 in pb.go files. - PROTOC_FILENAME=protoc-${PROTOBUF_VERSION}-linux-x86_64.zip - pushd /home/runner/go - wget https://github.com/google/protobuf/releases/download/v${PROTOBUF_VERSION}/${PROTOC_FILENAME} - unzip ${PROTOC_FILENAME} - bin/protoc --version - popd - elif not which protoc > /dev/null; then - die "Please install protoc into your path" - fi - fi - exit 0 -elif [[ "$#" -ne 0 ]]; then - die "Unknown argument(s): $*" -fi - -# - Check that generated proto files are up to date. -if [[ -z "${VET_SKIP_PROTO}" ]]; then - make proto && git status --porcelain 2>&1 | fail_on_output || \ - (git status; git --no-pager diff; exit 1) -fi - -if [[ -n "${VET_ONLY_PROTO}" ]]; then - exit 0 -fi - -# - Ensure all source files contain a copyright message. -# (Done in two parts because Darwin "git grep" has broken support for compound -# exclusion matches.) -(grep -L "DO NOT EDIT" $(git grep -L "\(Copyright [0-9]\{4,\} gRPC authors\)" -- '*.go') || true) | fail_on_output - -# - Make sure all tests in grpc and grpc/test use leakcheck via Teardown. -not grep 'func Test[^(]' *_test.go -not grep 'func Test[^(]' test/*.go - -# - Check for typos in test function names -git grep 'func (s) ' -- "*_test.go" | not grep -v 'func (s) Test' -git grep 'func [A-Z]' -- "*_test.go" | not grep -v 'func Test\|Benchmark\|Example' - -# - Do not import x/net/context. -not git grep -l 'x/net/context' -- "*.go" - -# - Do not use time.After except in tests. It has the potential to leak the -# timer since there is no way to stop it early. -git grep -l 'time.After(' -- "*.go" | not grep -v '_test.go\|test_utils\|testutils' - -# - Do not import math/rand for real library code. Use internal/grpcrand for -# thread safety. -git grep -l '"math/rand"' -- "*.go" 2>&1 | not grep -v '^examples\|^interop/stress\|grpcrand\|^benchmark\|wrr_test' - -# - Do not use "interface{}"; use "any" instead. -git grep -l 'interface{}' -- "*.go" 2>&1 | not grep -v '\.pb\.go\|protoc-gen-go-grpc\|grpc_testing_not_regenerate' - -# - Do not call grpclog directly. Use grpclog.Component instead. -git grep -l -e 'grpclog.I' --or -e 'grpclog.W' --or -e 'grpclog.E' --or -e 'grpclog.F' --or -e 'grpclog.V' -- "*.go" | not grep -v '^grpclog/component.go\|^internal/grpctest/tlogger_test.go' - -# - Ensure all ptypes proto packages are renamed when importing. -not git grep "\(import \|^\s*\)\"github.com/golang/protobuf/ptypes/" -- "*.go" - -# - Ensure all usages of grpc_testing package are renamed when importing. -not git grep "\(import \|^\s*\)\"google.golang.org/grpc/interop/grpc_testing" -- "*.go" - -# - Ensure all xds proto imports are renamed to *pb or *grpc. -git grep '"github.com/envoyproxy/go-control-plane/envoy' -- '*.go' ':(exclude)*.pb.go' | not grep -v 'pb "\|grpc "' - -misspell -error . - -# - gofmt, goimports, go vet, go mod tidy. -# Perform these checks on each module inside gRPC. -for MOD_FILE in $(find . -name 'go.mod'); do - MOD_DIR=$(dirname ${MOD_FILE}) - pushd ${MOD_DIR} - go vet -all ./... | fail_on_output - gofmt -s -d -l . 2>&1 | fail_on_output - goimports -l . 2>&1 | not grep -vE "\.pb\.go" - - go mod tidy -compat=1.19 - git status --porcelain 2>&1 | fail_on_output || \ - (git status; git --no-pager diff; exit 1) - popd -done - -# - Collection of static analysis checks -SC_OUT="$(mktemp)" -staticcheck -go 1.19 -checks 'all' ./... > "${SC_OUT}" || true - -# Error for anything other than checks that need exclusions. -grep -v "(ST1000)" "${SC_OUT}" | grep -v "(SA1019)" | grep -v "(ST1003)" | not grep -v "(ST1019)\|\(other import of\)" - -# Exclude underscore checks for generated code. -grep "(ST1003)" "${SC_OUT}" | not grep -v '\(.pb.go:\)\|\(code_string_test.go:\)\|\(grpc_testing_not_regenerate\)' - -# Error for duplicate imports not including grpc protos. -grep "(ST1019)\|\(other import of\)" "${SC_OUT}" | not grep -Fv 'XXXXX PleaseIgnoreUnused -channelz/grpc_channelz_v1" -go-control-plane/envoy -grpclb/grpc_lb_v1" -health/grpc_health_v1" -interop/grpc_testing" -orca/v3" -proto/grpc_gcp" -proto/grpc_lookup_v1" -reflection/grpc_reflection_v1" -reflection/grpc_reflection_v1alpha" -XXXXX PleaseIgnoreUnused' - -# Error for any package comments not in generated code. -grep "(ST1000)" "${SC_OUT}" | not grep -v "\.pb\.go:" - -# Only ignore the following deprecated types/fields/functions and exclude -# generated code. -grep "(SA1019)" "${SC_OUT}" | not grep -Fv 'XXXXX PleaseIgnoreUnused -XXXXX Protobuf related deprecation errors: -"github.com/golang/protobuf -.pb.go: -grpc_testing_not_regenerate -: ptypes. -proto.RegisterType -XXXXX gRPC internal usage deprecation errors: -"google.golang.org/grpc -: grpc. -: v1alpha. -: v1alphareflectionpb. -BalancerAttributes is deprecated: -CredsBundle is deprecated: -Metadata is deprecated: use Attributes instead. -NewSubConn is deprecated: -OverrideServerName is deprecated: -RemoveSubConn is deprecated: -SecurityVersion is deprecated: -Target is deprecated: Use the Target field in the BuildOptions instead. -UpdateAddresses is deprecated: -UpdateSubConnState is deprecated: -balancer.ErrTransientFailure is deprecated: -grpc/reflection/v1alpha/reflection.proto -SwitchTo is deprecated: -XXXXX xDS deprecated fields we support -.ExactMatch -.PrefixMatch -.SafeRegexMatch -.SuffixMatch -GetContainsMatch -GetExactMatch -GetMatchSubjectAltNames -GetPrefixMatch -GetSafeRegexMatch -GetSuffixMatch -GetTlsCertificateCertificateProviderInstance -GetValidationContextCertificateProviderInstance -XXXXX PleaseIgnoreUnused' - -echo SUCCESS diff --git a/vendor/modules.txt b/vendor/modules.txt index ebda72f7f6d..51103e9bb33 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,4 +1,4 @@ -# cloud.google.com/go/compute v1.24.0 +# cloud.google.com/go/compute v1.25.1 ## explicit; go 1.19 cloud.google.com/go/compute/internal # cloud.google.com/go/compute/metadata v0.2.3 @@ -1158,7 +1158,7 @@ google.golang.org/api/transport/http/internal/propagation ## explicit; go 1.19 google.golang.org/genproto/googleapis/cloud/location google.golang.org/genproto/googleapis/type/expr -# google.golang.org/genproto/googleapis/api v0.0.0-20240311132316-a219d84964c2 +# google.golang.org/genproto/googleapis/api v0.0.0-20240318140521-94a12d6c2237 ## explicit; go 1.19 google.golang.org/genproto/googleapis/api google.golang.org/genproto/googleapis/api/annotations @@ -1169,7 +1169,7 @@ google.golang.org/genproto/googleapis/api/httpbody google.golang.org/genproto/googleapis/rpc/code google.golang.org/genproto/googleapis/rpc/errdetails google.golang.org/genproto/googleapis/rpc/status -# google.golang.org/grpc v1.63.2 +# google.golang.org/grpc v1.64.0 ## explicit; go 1.19 google.golang.org/grpc google.golang.org/grpc/attributes From 71ce8456faa7dea86e046adb25ee1252906996e4 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Wed, 15 May 2024 19:00:46 +0000 Subject: [PATCH 14/23] chore(deps): bump k8s.io/api in /test/custom-task-ctrls/wait-task-beta Bumps [k8s.io/api](https://github.com/kubernetes/api) from 0.27.13 to 0.27.14. - [Commits](https://github.com/kubernetes/api/compare/v0.27.13...v0.27.14) --- updated-dependencies: - dependency-name: k8s.io/api dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- test/custom-task-ctrls/wait-task-beta/go.mod | 4 ++-- test/custom-task-ctrls/wait-task-beta/go.sum | 6 ++++-- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/test/custom-task-ctrls/wait-task-beta/go.mod b/test/custom-task-ctrls/wait-task-beta/go.mod index f49b3abda70..35c42a8111e 100644 --- a/test/custom-task-ctrls/wait-task-beta/go.mod +++ b/test/custom-task-ctrls/wait-task-beta/go.mod @@ -6,8 +6,8 @@ require ( github.com/emicklei/go-restful v2.16.0+incompatible // indirect github.com/google/go-cmp v0.6.0 github.com/tektoncd/pipeline v0.53.1 - k8s.io/api v0.27.13 - k8s.io/apimachinery v0.27.13 + k8s.io/api v0.27.14 + k8s.io/apimachinery v0.27.14 k8s.io/client-go v0.27.13 k8s.io/utils v0.0.0-20230505201702-9f6742963106 knative.dev/pkg v0.0.0-20231011193800-bd99f2f98be7 diff --git a/test/custom-task-ctrls/wait-task-beta/go.sum b/test/custom-task-ctrls/wait-task-beta/go.sum index 39cf8077312..e16db3717d4 100644 --- a/test/custom-task-ctrls/wait-task-beta/go.sum +++ b/test/custom-task-ctrls/wait-task-beta/go.sum @@ -3661,8 +3661,9 @@ k8s.io/api v0.23.6/go.mod h1:1kFaYxGCFHYp3qd6a85DAj/yW8aVD6XLZMqJclkoi9g= k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU= k8s.io/api v0.26.5/go.mod h1:O7ICW7lj6+ZQQQ3cxekgCoW+fnGo5kWT0nTHkLZ5grc= k8s.io/api v0.27.1/go.mod h1:z5g/BpAiD+f6AArpqNjkY+cji8ueZDU/WV1jcj5Jk4E= -k8s.io/api v0.27.13 h1:d49LYs1dh+JMMDNYQSu8FhEzCjc2TNpYvDWoSGAKs80= k8s.io/api v0.27.13/go.mod h1:W3lYMPs34i0XQA+cmKfejve+HwbRZjy67fL05RyJUTo= +k8s.io/api v0.27.14 h1:/oKAF9HiSB47polol2Ji2TaFnC400JK57jSPUXY5MzU= +k8s.io/api v0.27.14/go.mod h1:Jekhd9Kyo2CsmJlYbqZPXNwIxiHvyGJCdp0X56yDyvU= k8s.io/apiextensions-apiserver v0.26.5 h1:VJ946z9RjyCPn3qiz4Kus/UYjCRrdn1xUvEsJFvN5Yo= k8s.io/apiextensions-apiserver v0.26.5/go.mod h1:Olsde7ZNWnyz9rsL13iXYXmL1h7kWujtKeC3yWVCDPo= k8s.io/apimachinery v0.20.1/go.mod h1:WlLqWAHZGg07AeltaI0MV5uk1Omp8xaN0JGLY6gkRpU= @@ -3676,8 +3677,9 @@ k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5 k8s.io/apimachinery v0.26.5/go.mod h1:HUvk6wrOP4v22AIYqeCGSQ6xWCHo41J9d6psb3temAg= k8s.io/apimachinery v0.27.1/go.mod h1:5ikh59fK3AJ287GUvpUsryoMFtH9zj/ARfWCo3AyXTM= k8s.io/apimachinery v0.27.3/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= -k8s.io/apimachinery v0.27.13 h1:xDAnOWaRVNSkaKdfB0Ab11hixH90KGTbLwEHMloMjFM= k8s.io/apimachinery v0.27.13/go.mod h1:TWo+8wOIz3CytsrlI9k/LBWXLRr9dqf5hRSCbbggMAg= +k8s.io/apimachinery v0.27.14 h1:jAIGvPbvAg4XJysK7JPFa6DdjTR6vts4/p4Q6ZrcQ+4= +k8s.io/apimachinery v0.27.14/go.mod h1:TWo+8wOIz3CytsrlI9k/LBWXLRr9dqf5hRSCbbggMAg= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= k8s.io/apiserver v0.20.4/go.mod h1:Mc80thBKOyy7tbvFtB4kJv1kbdD0eIH8k8vianJcbFM= k8s.io/apiserver v0.20.6/go.mod h1:QIJXNt6i6JB+0YQRNcS0hdRHJlMhflFmsBDeSgT1r8Q= From 3ba243d7efdd9e4bd287160c38673ea68677111e Mon Sep 17 00:00:00 2001 From: Kewei Yang Date: Thu, 29 Feb 2024 15:06:02 +0800 Subject: [PATCH 15/23] Prior to this PR, when pipeline refers to a remote pipeline, in the pipeline-related metrics, the pipeline name tag will be set to 'anonymous'. Taskrun has the same situation. This commit added some scenarios for obtaining pipeline or task names. When the pipeline or task name cannot be determined accurately, the value is obtained through the corresponding label. --- pkg/pipelinerunmetrics/metrics.go | 27 +++++- pkg/pipelinerunmetrics/metrics_test.go | 45 ++++++++++ pkg/taskrunmetrics/metrics.go | 28 ++++-- pkg/taskrunmetrics/metrics_test.go | 120 ++++++++++++++++++++++++- 4 files changed, 207 insertions(+), 13 deletions(-) diff --git a/pkg/pipelinerunmetrics/metrics.go b/pkg/pipelinerunmetrics/metrics.go index c89428bd67f..3b6afcfa523 100644 --- a/pkg/pipelinerunmetrics/metrics.go +++ b/pkg/pipelinerunmetrics/metrics.go @@ -24,6 +24,7 @@ import ( "time" "github.com/tektoncd/pipeline/pkg/apis/config" + "github.com/tektoncd/pipeline/pkg/apis/pipeline" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" listers "github.com/tektoncd/pipeline/pkg/client/listers/pipeline/v1" "go.opencensus.io/stats" @@ -96,6 +97,8 @@ const ( // ReasonCancelled indicates that a PipelineRun was cancelled. // Aliased for backwards compatibility; additional reasons should not be added here. ReasonCancelled = v1.PipelineRunReasonCancelled + + anonymous = "anonymous" ) // Recorder holds keys for Tekton metrics @@ -291,6 +294,24 @@ func nilInsertTag(task, taskrun string) []tag.Mutator { return []tag.Mutator{} } +func getPipelineTagName(pr *v1.PipelineRun) string { + pipelineName := anonymous + switch { + case pr.Spec.PipelineRef != nil && pr.Spec.PipelineRef.Name != "": + pipelineName = pr.Spec.PipelineRef.Name + case pr.Spec.PipelineSpec != nil: + default: + if len(pr.Labels) > 0 { + pipelineLabel, hasPipelineLabel := pr.Labels[pipeline.PipelineLabelKey] + if hasPipelineLabel && len(pipelineLabel) > 0 { + pipelineName = pipelineLabel + } + } + } + + return pipelineName +} + // DurationAndCount logs the duration of PipelineRun execution and // count for number of PipelineRuns succeed or failed // returns an error if its failed to log the metrics @@ -326,10 +347,8 @@ func (r *Recorder) DurationAndCount(pr *v1.PipelineRun, beforeCondition *apis.Co } reason := cond.Reason - pipelineName := "anonymous" - if pr.Spec.PipelineRef != nil && pr.Spec.PipelineRef.Name != "" { - pipelineName = pr.Spec.PipelineRef.Name - } + pipelineName := getPipelineTagName(pr) + ctx, err := tag.New( context.Background(), append([]tag.Mutator{tag.Insert(namespaceTag, pr.Namespace), diff --git a/pkg/pipelinerunmetrics/metrics_test.go b/pkg/pipelinerunmetrics/metrics_test.go index 0633335008a..7ba170a7d2d 100644 --- a/pkg/pipelinerunmetrics/metrics_test.go +++ b/pkg/pipelinerunmetrics/metrics_test.go @@ -23,6 +23,8 @@ import ( "testing" "time" + "github.com/tektoncd/pipeline/pkg/apis/pipeline" + "github.com/tektoncd/pipeline/pkg/apis/config" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" fakepipelineruninformer "github.com/tektoncd/pipeline/pkg/client/injection/informers/pipeline/v1/pipelinerun/fake" @@ -386,6 +388,49 @@ func TestRecordPipelineRunDurationCount(t *testing.T) { expectedCount: 1, beforeCondition: nil, countWithReason: true, + }, { + name: "for failed pipeline with reference remote pipeline", + pipelineRun: &v1.PipelineRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipelinerun-1", + Namespace: "ns", + Labels: map[string]string{ + pipeline.PipelineLabelKey: "pipeline-remote", + }, + }, + Spec: v1.PipelineRunSpec{ + PipelineRef: &v1.PipelineRef{ + ResolverRef: v1.ResolverRef{ + Resolver: "git", + }, + }, + }, + Status: v1.PipelineRunStatus{ + Status: duckv1.Status{ + Conditions: duckv1.Conditions{{ + Type: apis.ConditionSucceeded, + Status: corev1.ConditionFalse, + }}, + }, + PipelineRunStatusFields: v1.PipelineRunStatusFields{ + StartTime: &startTime, + CompletionTime: &completionTime, + }, + }, + }, + expectedDurationTags: map[string]string{ + "pipeline": "pipeline-remote", + "pipelinerun": "pipelinerun-1", + "namespace": "ns", + "status": "failed", + }, + expectedCountTags: map[string]string{ + "status": "failed", + }, + expectedDuration: 60, + expectedCount: 1, + beforeCondition: nil, + countWithReason: false, }} { t.Run(test.name, func(t *testing.T) { unregisterMetrics() diff --git a/pkg/taskrunmetrics/metrics.go b/pkg/taskrunmetrics/metrics.go index 050398b24a6..594ac04fc3b 100644 --- a/pkg/taskrunmetrics/metrics.go +++ b/pkg/taskrunmetrics/metrics.go @@ -367,6 +367,24 @@ func nilInsertTag(task, taskrun string) []tag.Mutator { return []tag.Mutator{} } +func getTaskTagName(tr *v1.TaskRun) string { + taskName := anonymous + switch { + case tr.Spec.TaskRef != nil && len(tr.Spec.TaskRef.Name) > 0: + taskName = tr.Spec.TaskRef.Name + case tr.Spec.TaskSpec != nil: + default: + if len(tr.Labels) > 0 { + taskLabel, hasTaskLabel := tr.Labels[pipeline.TaskLabelKey] + if hasTaskLabel && len(taskLabel) > 0 { + taskName = taskLabel + } + } + } + + return taskName +} + // DurationAndCount logs the duration of TaskRun execution and // count for number of TaskRuns succeed or failed // returns an error if its failed to log the metrics @@ -388,10 +406,7 @@ func (r *Recorder) DurationAndCount(ctx context.Context, tr *v1.TaskRun, beforeC duration = tr.Status.CompletionTime.Sub(tr.Status.StartTime.Time) } - taskName := anonymous - if tr.Spec.TaskRef != nil { - taskName = tr.Spec.TaskRef.Name - } + taskName := getTaskTagName(tr) cond := tr.Status.GetCondition(apis.ConditionSucceeded) status := "success" @@ -550,10 +565,7 @@ func (r *Recorder) RecordPodLatency(ctx context.Context, pod *corev1.Pod, tr *v1 } latency := scheduledTime.Sub(pod.CreationTimestamp.Time) - taskName := anonymous - if tr.Spec.TaskRef != nil { - taskName = tr.Spec.TaskRef.Name - } + taskName := getTaskTagName(tr) ctx, err := tag.New( ctx, diff --git a/pkg/taskrunmetrics/metrics_test.go b/pkg/taskrunmetrics/metrics_test.go index e58a2dcb849..b38748cb13b 100644 --- a/pkg/taskrunmetrics/metrics_test.go +++ b/pkg/taskrunmetrics/metrics_test.go @@ -273,6 +273,50 @@ func TestRecordTaskRunDurationCount(t *testing.T) { expectedCount: 1, beforeCondition: nil, countWithReason: false, + }, { + name: "for failed taskrun with reference remote task", + taskRun: &v1.TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "taskrun-1", + Namespace: "ns", + Labels: map[string]string{ + pipeline.TaskLabelKey: "task-remote", + }, + }, + Spec: v1.TaskRunSpec{ + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{ + Resolver: "git", + }, + }, + }, + Status: v1.TaskRunStatus{ + Status: duckv1.Status{ + Conditions: duckv1.Conditions{{ + Type: apis.ConditionSucceeded, + Status: corev1.ConditionFalse, + }}, + }, + TaskRunStatusFields: v1.TaskRunStatusFields{ + StartTime: &startTime, + CompletionTime: &completionTime, + }, + }, + }, + metricName: "taskrun_duration_seconds", + expectedDurationTags: map[string]string{ + "task": "task-remote", + "taskrun": "taskrun-1", + "namespace": "ns", + "status": "failed", + }, + expectedCountTags: map[string]string{ + "status": "failed", + }, + expectedDuration: 60, + expectedCount: 1, + beforeCondition: nil, + countWithReason: false, }, { name: "for succeeded taskrun in pipelinerun", taskRun: &v1.TaskRun{ @@ -596,12 +640,38 @@ func TestRecordPodLatency(t *testing.T) { TaskRef: &v1.TaskRef{Name: "task-1"}, }, } + trFromRemoteTask := &v1.TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun", + Namespace: "foo", + Labels: map[string]string{ + pipeline.TaskLabelKey: "task-remote", + }, + }, + Spec: v1.TaskRunSpec{ + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{Resolver: "task-remote"}, + }, + }, + } + emptyLabelTRFromRemoteTask := &v1.TaskRun{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun", + Namespace: "foo", + }, + Spec: v1.TaskRunSpec{ + TaskRef: &v1.TaskRef{ + ResolverRef: v1.ResolverRef{Resolver: "task-remote"}, + }, + }, + } for _, td := range []struct { name string pod *corev1.Pod expectedTags map[string]string expectedValue float64 expectingError bool + taskRun *v1.TaskRun }{{ name: "for scheduled pod", pod: &corev1.Pod{ @@ -624,6 +694,53 @@ func TestRecordPodLatency(t *testing.T) { "namespace": "foo", }, expectedValue: 4000, + taskRun: taskRun, + }, { + name: "for scheduled pod with reference remote task", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun-pod-123456", + Namespace: "foo", + CreationTimestamp: creationTime, + }, + Status: corev1.PodStatus{ + Conditions: []corev1.PodCondition{{ + Type: corev1.PodScheduled, + LastTransitionTime: metav1.Time{Time: creationTime.Add(4 * time.Second)}, + }}, + }, + }, + expectedTags: map[string]string{ + "pod": "test-taskrun-pod-123456", + "task": "task-remote", + "taskrun": "test-taskrun", + "namespace": "foo", + }, + expectedValue: 4000, + taskRun: trFromRemoteTask, + }, { + name: "for scheduled pod - empty label tr reference remote task", + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-taskrun-pod-123456", + Namespace: "foo", + CreationTimestamp: creationTime, + }, + Status: corev1.PodStatus{ + Conditions: []corev1.PodCondition{{ + Type: corev1.PodScheduled, + LastTransitionTime: metav1.Time{Time: creationTime.Add(4 * time.Second)}, + }}, + }, + }, + expectedTags: map[string]string{ + "pod": "test-taskrun-pod-123456", + "task": anonymous, + "taskrun": "test-taskrun", + "namespace": "foo", + }, + expectedValue: 4000, + taskRun: emptyLabelTRFromRemoteTask, }, { name: "for non scheduled pod", pod: &corev1.Pod{ @@ -635,6 +752,7 @@ func TestRecordPodLatency(t *testing.T) { Status: corev1.PodStatus{}, }, expectingError: true, + taskRun: taskRun, }} { t.Run(td.name, func(t *testing.T) { unregisterMetrics() @@ -645,7 +763,7 @@ func TestRecordPodLatency(t *testing.T) { t.Fatalf("NewRecorder: %v", err) } - if err := metrics.RecordPodLatency(ctx, td.pod, taskRun); td.expectingError && err == nil { + if err := metrics.RecordPodLatency(ctx, td.pod, td.taskRun); td.expectingError && err == nil { t.Error("RecordPodLatency wanted error, got nil") } else if !td.expectingError { if err != nil { From dc13d902abeb60398841905e11544233c6316dfe Mon Sep 17 00:00:00 2001 From: Pavol Pitonak Date: Thu, 11 Apr 2024 16:49:55 +0200 Subject: [PATCH 16/23] v1beta1 fields updated to v1 in docs and examples Signed-off-by: Pavol Pitonak --- docs/pipeline-api.md | 4 ++-- docs/windows.md | 10 +++++----- .../pipelineruns/no-ci/pipelinerun-taskrunspecs.yaml | 2 +- .../v1/pipelineruns/no-ci/windows-node-affinity.yaml | 2 +- .../v1/pipelineruns/no-ci/windows-node-selectors.yaml | 2 +- 5 files changed, 10 insertions(+), 10 deletions(-) diff --git a/docs/pipeline-api.md b/docs/pipeline-api.md index d635d006cd6..a664fb72414 100644 --- a/docs/pipeline-api.md +++ b/docs/pipeline-api.md @@ -12565,7 +12565,7 @@ string -taskServiceAccountName
    +serviceAccountName
    string @@ -12575,7 +12575,7 @@ string -taskPodTemplate
    +podTemplate
    Template diff --git a/docs/windows.md b/docs/windows.md index fc3b39bd1dc..93c95f6b7b4 100644 --- a/docs/windows.md +++ b/docs/windows.md @@ -36,12 +36,12 @@ In order to ensure that Tasks are scheduled to a node with the correct host OS, ### Node Selectors -Node selectors are the simplest way to schedule pods to a Windows or Linux node. By default, Kubernetes nodes include a label `kubernetes.io/os` to identify the host OS. The Kubelet populates this with `runtime.GOOS` as defined by Go. Use `spec.podTemplate.nodeSelector` (or `spec.taskRunSpecs[i].taskPodTemplate.nodeSelector` in a PipelineRun) to schedule Tasks to a node with a specific label and value. +Node selectors are the simplest way to schedule pods to a Windows or Linux node. By default, Kubernetes nodes include a label `kubernetes.io/os` to identify the host OS. The Kubelet populates this with `runtime.GOOS` as defined by Go. Use `spec.podTemplate.nodeSelector` (or `spec.taskRunSpecs[i].podTemplate.nodeSelector` in a PipelineRun) to schedule Tasks to a node with a specific label and value. For example: ``` yaml -apiVersion: tekton.dev/v1beta1 +apiVersion: tekton.dev/v1 kind: TaskRun metadata: name: windows-taskrun @@ -52,7 +52,7 @@ spec: nodeSelector: kubernetes.io/os: windows --- -apiVersion: tekton.dev/v1beta1 +apiVersion: tekton.dev/v1 kind: TaskRun metadata: name: linux-taskrun @@ -71,7 +71,7 @@ Node affinity can be used as an alternative method of defining the OS requiremen For example: ```yaml -apiVersion: tekton.dev/v1beta1 +apiVersion: tekton.dev/v1 kind: TaskRun metadata: name: windows-taskrun @@ -89,7 +89,7 @@ spec: values: - windows --- -apiVersion: tekton.dev/v1beta1 +apiVersion: tekton.dev/v1 kind: TaskRun metadata: name: linux-taskrun diff --git a/examples/v1/pipelineruns/no-ci/pipelinerun-taskrunspecs.yaml b/examples/v1/pipelineruns/no-ci/pipelinerun-taskrunspecs.yaml index e0de92d4ee6..a6e1e345194 100644 --- a/examples/v1/pipelineruns/no-ci/pipelinerun-taskrunspecs.yaml +++ b/examples/v1/pipelineruns/no-ci/pipelinerun-taskrunspecs.yaml @@ -74,7 +74,7 @@ spec: - pipelineTaskName: first-add-taskspec serviceAccountName: 'default' - pipelineTaskName: second-add-taskspec - taskPodTemplate: + podTemplate: nodeSelector: disktype: ssd params: diff --git a/examples/v1/pipelineruns/no-ci/windows-node-affinity.yaml b/examples/v1/pipelineruns/no-ci/windows-node-affinity.yaml index 7dc33d58917..21b54af2ec2 100644 --- a/examples/v1/pipelineruns/no-ci/windows-node-affinity.yaml +++ b/examples/v1/pipelineruns/no-ci/windows-node-affinity.yaml @@ -31,7 +31,7 @@ spec: name: windows-pipeline-na taskRunSpecs: - pipelineTaskName: windows-task-na - taskPodTemplate: + podTemplate: affinity: nodeAffinity: requiredDuringSchedulingIgnoredDuringExecution: diff --git a/examples/v1/pipelineruns/no-ci/windows-node-selectors.yaml b/examples/v1/pipelineruns/no-ci/windows-node-selectors.yaml index ced1bef6b54..06894ed9af1 100644 --- a/examples/v1/pipelineruns/no-ci/windows-node-selectors.yaml +++ b/examples/v1/pipelineruns/no-ci/windows-node-selectors.yaml @@ -31,6 +31,6 @@ spec: name: windows-pipeline-ns taskRunSpecs: - pipelineTaskName: windows-task-ns - taskPodTemplate: + podTemplate: nodeSelector: kubernetes.io/os: windows From fa10a89614284e290c4c5291842ecc84bf02a82e Mon Sep 17 00:00:00 2001 From: Pavol Pitonak Date: Fri, 12 Apr 2024 11:24:26 +0200 Subject: [PATCH 17/23] change in pipeline-api.md reverted --- docs/pipeline-api.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/pipeline-api.md b/docs/pipeline-api.md index a664fb72414..d635d006cd6 100644 --- a/docs/pipeline-api.md +++ b/docs/pipeline-api.md @@ -12565,7 +12565,7 @@ string -serviceAccountName
    +taskServiceAccountName
    string @@ -12575,7 +12575,7 @@ string -podTemplate
    +taskPodTemplate
    Template From ee68bcc619a1392605a1c55b49692c44e7f99c54 Mon Sep 17 00:00:00 2001 From: Sachin Itagi Date: Fri, 10 May 2024 04:20:53 +0000 Subject: [PATCH 18/23] Add image replacement for amd64 specific image Signed-off-by: Sachin Itagi --- test/examples_test.go | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/test/examples_test.go b/test/examples_test.go index 74a74909858..3880bc42022 100644 --- a/test/examples_test.go +++ b/test/examples_test.go @@ -280,13 +280,14 @@ func imageNamesMapping() map[string]string { } case "ppc64le": return map[string]string{ - "registry": getTestImage(registryImage), - "node": "node:alpine3.11", - "gcr.io/cloud-builders/git": "alpine/git:latest", - "docker:dind": "ibmcom/docker-ppc64le:19.03-dind", + "registry": getTestImage(registryImage), + "node": "node:alpine3.11", + "gcr.io/cloud-builders/git": "alpine/git:latest", + "docker@sha256:74e78208fc18da48ddf8b569abe21563730845c312130bd0f0b059746a7e10f5": "ibmcom/docker-ppc64le:19.03-dind", "docker": "docker:18.06.3", "mikefarah/yq:3": "danielxlee/yq:2.4.0", "stedolan/jq": "ibmcom/jq-ppc64le:latest", + "amd64/ubuntu": "ppc64le/ubuntu", "gcr.io/kaniko-project/executor:v1.3.0": getTestImage(kanikoImage), } } From f95c4b7be35cc4574d3644834d1315363140537d Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Thu, 16 May 2024 10:36:51 +0000 Subject: [PATCH 19/23] chore(deps): bump k8s.io/client-go Bumps [k8s.io/client-go](https://github.com/kubernetes/client-go) from 0.27.13 to 0.27.14. - [Changelog](https://github.com/kubernetes/client-go/blob/master/CHANGELOG.md) - [Commits](https://github.com/kubernetes/client-go/compare/v0.27.13...v0.27.14) --- updated-dependencies: - dependency-name: k8s.io/client-go dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] --- test/custom-task-ctrls/wait-task-beta/go.mod | 2 +- test/custom-task-ctrls/wait-task-beta/go.sum | 6 ++---- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/test/custom-task-ctrls/wait-task-beta/go.mod b/test/custom-task-ctrls/wait-task-beta/go.mod index 35c42a8111e..01cd3d478a5 100644 --- a/test/custom-task-ctrls/wait-task-beta/go.mod +++ b/test/custom-task-ctrls/wait-task-beta/go.mod @@ -8,7 +8,7 @@ require ( github.com/tektoncd/pipeline v0.53.1 k8s.io/api v0.27.14 k8s.io/apimachinery v0.27.14 - k8s.io/client-go v0.27.13 + k8s.io/client-go v0.27.14 k8s.io/utils v0.0.0-20230505201702-9f6742963106 knative.dev/pkg v0.0.0-20231011193800-bd99f2f98be7 ) diff --git a/test/custom-task-ctrls/wait-task-beta/go.sum b/test/custom-task-ctrls/wait-task-beta/go.sum index e16db3717d4..9742e1d390f 100644 --- a/test/custom-task-ctrls/wait-task-beta/go.sum +++ b/test/custom-task-ctrls/wait-task-beta/go.sum @@ -3661,7 +3661,6 @@ k8s.io/api v0.23.6/go.mod h1:1kFaYxGCFHYp3qd6a85DAj/yW8aVD6XLZMqJclkoi9g= k8s.io/api v0.26.2/go.mod h1:1kjMQsFE+QHPfskEcVNgL3+Hp88B80uj0QtSOlj8itU= k8s.io/api v0.26.5/go.mod h1:O7ICW7lj6+ZQQQ3cxekgCoW+fnGo5kWT0nTHkLZ5grc= k8s.io/api v0.27.1/go.mod h1:z5g/BpAiD+f6AArpqNjkY+cji8ueZDU/WV1jcj5Jk4E= -k8s.io/api v0.27.13/go.mod h1:W3lYMPs34i0XQA+cmKfejve+HwbRZjy67fL05RyJUTo= k8s.io/api v0.27.14 h1:/oKAF9HiSB47polol2Ji2TaFnC400JK57jSPUXY5MzU= k8s.io/api v0.27.14/go.mod h1:Jekhd9Kyo2CsmJlYbqZPXNwIxiHvyGJCdp0X56yDyvU= k8s.io/apiextensions-apiserver v0.26.5 h1:VJ946z9RjyCPn3qiz4Kus/UYjCRrdn1xUvEsJFvN5Yo= @@ -3677,7 +3676,6 @@ k8s.io/apimachinery v0.26.2/go.mod h1:ats7nN1LExKHvJ9TmwootT00Yz05MuYqPXEXaVeOy5 k8s.io/apimachinery v0.26.5/go.mod h1:HUvk6wrOP4v22AIYqeCGSQ6xWCHo41J9d6psb3temAg= k8s.io/apimachinery v0.27.1/go.mod h1:5ikh59fK3AJ287GUvpUsryoMFtH9zj/ARfWCo3AyXTM= k8s.io/apimachinery v0.27.3/go.mod h1:XNfZ6xklnMCOGGFNqXG7bUrQCoR04dh/E7FprV6pb+E= -k8s.io/apimachinery v0.27.13/go.mod h1:TWo+8wOIz3CytsrlI9k/LBWXLRr9dqf5hRSCbbggMAg= k8s.io/apimachinery v0.27.14 h1:jAIGvPbvAg4XJysK7JPFa6DdjTR6vts4/p4Q6ZrcQ+4= k8s.io/apimachinery v0.27.14/go.mod h1:TWo+8wOIz3CytsrlI9k/LBWXLRr9dqf5hRSCbbggMAg= k8s.io/apiserver v0.20.1/go.mod h1:ro5QHeQkgMS7ZGpvf4tSMx6bBOgPfE+f52KwvXfScaU= @@ -3694,8 +3692,8 @@ k8s.io/client-go v0.23.6/go.mod h1:Umt5icFOMLV/+qbtZ3PR0D+JA6lvvb3syzodv4irpK4= k8s.io/client-go v0.26.2/go.mod h1:u5EjOuSyBa09yqqyY7m3abZeovO/7D/WehVVlZ2qcqU= k8s.io/client-go v0.26.5/go.mod h1:/CYyNt+ZLMvWqMF8h1SvkUXz2ujFWQLwdDrdiQlZ5X0= k8s.io/client-go v0.27.1/go.mod h1:f8LHMUkVb3b9N8bWturc+EDtVVVwZ7ueTVquFAJb2vA= -k8s.io/client-go v0.27.13 h1:SfUbIukb6BSqaadlYRX0AzMoN6+e+9FZGEKqfisidho= -k8s.io/client-go v0.27.13/go.mod h1:I9SBaI28r6ii465Fb0dTpf5O3adOnDwNBoeqlDNbbFg= +k8s.io/client-go v0.27.14 h1:5KwfSakOTQFRlPru2Ql/wp1URjPgzoP7QpTlEH9a+ys= +k8s.io/client-go v0.27.14/go.mod h1:cy+p3ijvbPQpdcwg01qnHBmkYDtbOatNC83anA9y18g= k8s.io/code-generator v0.19.7/go.mod h1:lwEq3YnLYb/7uVXLorOJfxg+cUu2oihFhHZ0n9NIla0= k8s.io/code-generator v0.26.5/go.mod h1:iWTVFxfBX+RYe0bXjKqSM83KJF8eimor/izQInvq/60= k8s.io/component-base v0.20.1/go.mod h1:guxkoJnNoh8LNrbtiQOlyp2Y2XFCZQmrcg2n/DeYNLk= From 13f45bf77c788762d10d9cf275496d73fe08a599 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Wed, 15 May 2024 10:48:35 -0400 Subject: [PATCH 20/23] allow for retry on typically transient k8s errors in both core controller and resolver for remote resolution During both sides of remote resolution (core controller and resolver) typically transient kubernetes errors were being treated as permanent knative errors and no attempts at trying to reconcile again were made, leading to failures which could be avoided. Then, while diagnosing this, discovered the TaskNotFoundError was missing the Task name when identification comes from params. That is also addressed. --- pkg/reconciler/pipelinerun/pipelinerun.go | 3 +- .../resources/pipelinerunresolution.go | 7 +- .../resources/pipelinerunresolution_test.go | 15 +++ pkg/reconciler/taskrun/resources/taskref.go | 11 --- pkg/reconciler/taskrun/taskrun.go | 5 +- pkg/reconciler/taskrun/taskrun_test.go | 66 +++++++------ .../resolver/framework/reconciler.go | 5 + .../resolver/framework/reconciler_test.go | 5 + pkg/resolution/common/errors.go | 27 ++++++ pkg/resolution/resolver/bundle/params.go | 3 +- .../resolver/framework/reconciler_test.go | 2 +- pkg/resolution/resolver/git/params.go | 4 +- pkg/resolution/resolver/http/params.go | 4 +- pkg/resolution/resolver/hub/params.go | 4 +- pkg/resolution/resource/name.go | 35 +++++++ pkg/resolution/resource/name_test.go | 95 +++++++++++++++++++ 16 files changed, 242 insertions(+), 49 deletions(-) diff --git a/pkg/reconciler/pipelinerun/pipelinerun.go b/pkg/reconciler/pipelinerun/pipelinerun.go index 2b4d8778dde..a959ca51434 100644 --- a/pkg/reconciler/pipelinerun/pipelinerun.go +++ b/pkg/reconciler/pipelinerun/pipelinerun.go @@ -53,6 +53,7 @@ import ( "github.com/tektoncd/pipeline/pkg/reconciler/volumeclaim" "github.com/tektoncd/pipeline/pkg/remote" resolution "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" + resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" "github.com/tektoncd/pipeline/pkg/substitution" "github.com/tektoncd/pipeline/pkg/trustedresources" "github.com/tektoncd/pipeline/pkg/workspace" @@ -373,7 +374,7 @@ func (c *Reconciler) resolvePipelineState( pst, ) if err != nil { - if tresources.IsErrTransient(err) { + if resolutioncommon.IsErrTransient(err) { return nil, err } if errors.Is(err, remote.ErrRequestInProgress) { diff --git a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go index a06b50d156e..6f78d31ba4d 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go +++ b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go @@ -31,6 +31,7 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1beta1" "github.com/tektoncd/pipeline/pkg/reconciler/taskrun/resources" "github.com/tektoncd/pipeline/pkg/remote" + "github.com/tektoncd/pipeline/pkg/resolution/resource" "github.com/tektoncd/pipeline/pkg/substitution" kerrors "k8s.io/apimachinery/pkg/api/errors" "knative.dev/pkg/apis" @@ -645,8 +646,12 @@ func resolveTask( case errors.Is(err, remote.ErrRequestInProgress): return rt, err case err != nil: + name := pipelineTask.TaskRef.Name + if len(strings.TrimSpace(name)) == 0 { + name = resource.GenerateErrorLogString(string(pipelineTask.TaskRef.Resolver), pipelineTask.TaskRef.Params) + } return rt, &TaskNotFoundError{ - Name: pipelineTask.TaskRef.Name, + Name: name, Msg: err.Error(), } default: diff --git a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go index fe6deee7c78..4f101c5beac 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go +++ b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution_test.go @@ -2490,6 +2490,18 @@ func TestResolvePipelineRun_TaskDoesntExist(t *testing.T) { Value: *v1.NewStructuredValues("b", "a", "r"), }}, }, + }, { + Name: "mytask3", + TaskRef: &v1.TaskRef{ResolverRef: v1.ResolverRef{Params: v1.Params{{Name: "name", Value: v1.ParamValue{Type: v1.ParamTypeString, StringVal: "foo"}}}}}, + Matrix: &v1.Matrix{ + Params: v1.Params{{ + Name: "foo", + Value: *v1.NewStructuredValues("f", "o", "o"), + }, { + Name: "bar", + Value: *v1.NewStructuredValues("b", "a", "r"), + }}, + }, }} // Return an error when the Task is retrieved, as if it didn't exist @@ -2512,6 +2524,9 @@ func TestResolvePipelineRun_TaskDoesntExist(t *testing.T) { t.Fatalf("Pipeline %s: want error, got nil", p.Name) case errors.As(err, &tnf): // expected error + if len(tnf.Name) == 0 { + t.Fatalf("Pipeline %s: TaskNotFoundError did not have name set: %s", p.Name, tnf.Error()) + } default: t.Fatalf("Pipeline %s: Want %T, got %s of type %T", p.Name, tnf, err, err) } diff --git a/pkg/reconciler/taskrun/resources/taskref.go b/pkg/reconciler/taskrun/resources/taskref.go index 03cea99ee25..2eea6da67a7 100644 --- a/pkg/reconciler/taskrun/resources/taskref.go +++ b/pkg/reconciler/taskrun/resources/taskref.go @@ -39,12 +39,6 @@ import ( "knative.dev/pkg/kmeta" ) -// This error is defined in etcd at -// https://github.com/etcd-io/etcd/blob/5b226e0abf4100253c94bb71f47d6815877ed5a2/server/etcdserver/errors.go#L30 -// TODO: If/when https://github.com/kubernetes/kubernetes/issues/106491 is addressed, -// we should stop relying on a hardcoded string. -var errEtcdLeaderChange = "etcdserver: leader changed" - // GetTaskKind returns the referenced Task kind (Task, ClusterTask, ...) if the TaskRun is using TaskRef. func GetTaskKind(taskrun *v1.TaskRun) v1.TaskKind { kind := v1.NamespacedTaskKind @@ -366,11 +360,6 @@ func (l *LocalStepActionRefResolver) GetStepAction(ctx context.Context, name str return stepAction, nil, nil } -// IsErrTransient returns true if an error returned by GetTask/GetStepAction is retryable. -func IsErrTransient(err error) bool { - return strings.Contains(err.Error(), errEtcdLeaderChange) -} - // convertClusterTaskToTask converts deprecated v1beta1 ClusterTasks to Tasks for // the rest of reconciling process since GetTask func and its upstream callers only // fetches the task spec and stores it in the taskrun status while the kind info diff --git a/pkg/reconciler/taskrun/taskrun.go b/pkg/reconciler/taskrun/taskrun.go index ebd744d05b7..b51daad6e11 100644 --- a/pkg/reconciler/taskrun/taskrun.go +++ b/pkg/reconciler/taskrun/taskrun.go @@ -48,6 +48,7 @@ import ( "github.com/tektoncd/pipeline/pkg/reconciler/volumeclaim" "github.com/tektoncd/pipeline/pkg/remote" resolution "github.com/tektoncd/pipeline/pkg/remoteresolution/resource" + resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" "github.com/tektoncd/pipeline/pkg/spire" "github.com/tektoncd/pipeline/pkg/taskrunmetrics" _ "github.com/tektoncd/pipeline/pkg/taskrunmetrics/fake" // Make sure the taskrunmetrics are setup @@ -409,7 +410,7 @@ func (c *Reconciler) prepare(ctx context.Context, tr *v1.TaskRun) (*v1.TaskSpec, return nil, nil, err case err != nil: logger.Errorf("Failed to determine Task spec to use for taskrun %s: %v", tr.Name, err) - if resources.IsErrTransient(err) { + if resolutioncommon.IsErrTransient(err) { return nil, nil, err } tr.Status.MarkResourceFailed(v1.TaskRunReasonFailedResolution, err) @@ -434,7 +435,7 @@ func (c *Reconciler) prepare(ctx context.Context, tr *v1.TaskRun) (*v1.TaskSpec, return nil, nil, err case err != nil: logger.Errorf("Failed to determine StepAction to use for TaskRun %s: %v", tr.Name, err) - if resources.IsErrTransient(err) { + if resolutioncommon.IsErrTransient(err) { return nil, nil, err } tr.Status.MarkResourceFailed(v1.TaskRunReasonFailedResolution, err) diff --git a/pkg/reconciler/taskrun/taskrun_test.go b/pkg/reconciler/taskrun/taskrun_test.go index e945a7d1fe3..de97cb34089 100644 --- a/pkg/reconciler/taskrun/taskrun_test.go +++ b/pkg/reconciler/taskrun/taskrun_test.go @@ -1965,38 +1965,46 @@ spec: Tasks: []*v1.Task{simpleTask}, ClusterTasks: []*v1beta1.ClusterTask{}, } - testAssets, cancel := getTaskRunController(t, d) - defer cancel() - c := testAssets.Controller - clients := testAssets.Clients - createServiceAccount(t, testAssets, "default", tr.Namespace) + for _, v := range []error{ + errors.New("etcdserver: leader changed"), + context.DeadlineExceeded, + apierrors.NewConflict(pipeline.TaskRunResource, "", nil), + apierrors.NewServerTimeout(pipeline.TaskRunResource, "", 0), + apierrors.NewTimeoutError("", 0), + } { + testAssets, cancel := getTaskRunController(t, d) + defer cancel() + c := testAssets.Controller + clients := testAssets.Clients + createServiceAccount(t, testAssets, "default", tr.Namespace) - failingReactorActivated := true - clients.Pipeline.PrependReactor("*", "tasks", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) { - return failingReactorActivated, &v1.Task{}, errors.New("etcdserver: leader changed") - }) - err := c.Reconciler.Reconcile(testAssets.Ctx, getRunName(tr)) - if err == nil { - t.Error("Wanted a wrapped error, but got nil.") - } - if controller.IsPermanentError(err) { - t.Errorf("Unexpected permanent error %v", err) - } + failingReactorActivated := true + clients.Pipeline.PrependReactor("*", "tasks", func(action ktesting.Action) (handled bool, ret runtime.Object, err error) { + return failingReactorActivated, &v1.Task{}, v + }) + err := c.Reconciler.Reconcile(testAssets.Ctx, getRunName(tr)) + if err == nil { + t.Error("Wanted a wrapped error, but got nil.") + } + if controller.IsPermanentError(err) { + t.Errorf("Unexpected permanent error %v", err) + } - failingReactorActivated = false - err = c.Reconciler.Reconcile(testAssets.Ctx, getRunName(tr)) - if err != nil { - if ok, _ := controller.IsRequeueKey(err); !ok { - t.Errorf("unexpected error in TaskRun reconciliation: %v", err) + failingReactorActivated = false + err = c.Reconciler.Reconcile(testAssets.Ctx, getRunName(tr)) + if err != nil { + if ok, _ := controller.IsRequeueKey(err); !ok { + t.Errorf("unexpected error in TaskRun reconciliation: %v", err) + } + } + reconciledRun, err := clients.Pipeline.TektonV1().TaskRuns("foo").Get(testAssets.Ctx, tr.Name, metav1.GetOptions{}) + if err != nil { + t.Fatalf("Somehow had error getting reconciled run out of fake client: %s", err) + } + condition := reconciledRun.Status.GetCondition(apis.ConditionSucceeded) + if !condition.IsUnknown() { + t.Errorf("Expected TaskRun to still be running but succeeded condition is %v", condition.Status) } - } - reconciledRun, err := clients.Pipeline.TektonV1().TaskRuns("foo").Get(testAssets.Ctx, tr.Name, metav1.GetOptions{}) - if err != nil { - t.Fatalf("Somehow had error getting reconciled run out of fake client: %s", err) - } - condition := reconciledRun.Status.GetCondition(apis.ConditionSucceeded) - if !condition.IsUnknown() { - t.Errorf("Expected TaskRun to still be running but succeeded condition is %v", condition.Status) } } diff --git a/pkg/remoteresolution/resolver/framework/reconciler.go b/pkg/remoteresolution/resolver/framework/reconciler.go index c4fb6177075..96a3d223132 100644 --- a/pkg/remoteresolution/resolver/framework/reconciler.go +++ b/pkg/remoteresolution/resolver/framework/reconciler.go @@ -169,6 +169,9 @@ func (r *Reconciler) resolve(ctx context.Context, key string, rr *v1beta1.Resolu // OnError is used to handle any situation where a ResolutionRequest has // reached a terminal situation that cannot be recovered from. func (r *Reconciler) OnError(ctx context.Context, rr *v1beta1.ResolutionRequest, err error) error { + if resolutioncommon.IsErrTransient(err) { + return err + } if rr == nil { return controller.NewPermanentError(err) } @@ -213,6 +216,7 @@ func (r *Reconciler) writeResolvedData(ctx context.Context, rr *v1beta1.Resoluti }, }) if err != nil { + logging.FromContext(ctx).Warnf("writeResolvedData error serializing resource request patch for resolution request %s:%s: %s", rr.Namespace, rr.Name, err.Error()) return r.OnError(ctx, rr, &resolutioncommon.UpdatingRequestError{ ResolutionRequestKey: fmt.Sprintf("%s/%s", rr.Namespace, rr.Name), Original: fmt.Errorf("error serializing resource request patch: %w", err), @@ -220,6 +224,7 @@ func (r *Reconciler) writeResolvedData(ctx context.Context, rr *v1beta1.Resoluti } _, err = r.resolutionRequestClientSet.ResolutionV1beta1().ResolutionRequests(rr.Namespace).Patch(ctx, rr.Name, types.MergePatchType, patchBytes, metav1.PatchOptions{}, "status") if err != nil { + logging.FromContext(ctx).Warnf("writeResolvedData error patching resolution request %s:%s: %s", rr.Namespace, rr.Name, err.Error()) return r.OnError(ctx, rr, &resolutioncommon.UpdatingRequestError{ ResolutionRequestKey: fmt.Sprintf("%s/%s", rr.Namespace, rr.Name), Original: err, diff --git a/pkg/remoteresolution/resolver/framework/reconciler_test.go b/pkg/remoteresolution/resolver/framework/reconciler_test.go index 6c11ecc8a0f..1a437ddfc89 100644 --- a/pkg/remoteresolution/resolver/framework/reconciler_test.go +++ b/pkg/remoteresolution/resolver/framework/reconciler_test.go @@ -63,6 +63,7 @@ func TestReconcile(t *testing.T) { reconcilerTimeout time.Duration expectedStatus *v1beta1.ResolutionRequestStatus expectedErr error + transient bool }{ { name: "unknown value", @@ -343,6 +344,7 @@ func TestReconcile(t *testing.T) { }, reconcilerTimeout: 1 * time.Second, expectedErr: errors.New("context deadline exceeded"), + transient: true, }, } @@ -369,6 +371,9 @@ func TestReconcile(t *testing.T) { if tc.expectedErr.Error() != err.Error() { t.Fatalf("expected to get error %v, but got %v", tc.expectedErr, err) } + if tc.transient && controller.IsPermanentError(err) { + t.Fatalf("exepected error to not be wrapped as permanent %v", err) + } } else { if err != nil { if ok, _ := controller.IsRequeueKey(err); !ok { diff --git a/pkg/resolution/common/errors.go b/pkg/resolution/common/errors.go index bb680f7fb56..d304989b8b8 100644 --- a/pkg/resolution/common/errors.go +++ b/pkg/resolution/common/errors.go @@ -17,10 +17,21 @@ limitations under the License. package common import ( + "context" "errors" "fmt" + "slices" + "strings" + + apierrors "k8s.io/apimachinery/pkg/api/errors" ) +// This error is defined in etcd at +// https://github.com/etcd-io/etcd/blob/5b226e0abf4100253c94bb71f47d6815877ed5a2/server/etcdserver/errors.go#L30 +// TODO: If/when https://github.com/kubernetes/kubernetes/issues/106491 is addressed, +// we should stop relying on a hardcoded string. +var errEtcdLeaderChange = "etcdserver: leader changed" + // Error embeds both a short machine-readable string reason for resolution // problems alongside the original error generated during the resolution flow. type Error struct { @@ -165,3 +176,19 @@ func ReasonError(err error) (string, error) { return reason, resolutionError } + +// IsErrTransient returns true if an error returned by GetTask/GetStepAction is retryable. +func IsErrTransient(err error) bool { + switch { + case apierrors.IsConflict(err): + return true + case apierrors.IsServerTimeout(err): + return true + case apierrors.IsTimeout(err): + return true + default: + return slices.ContainsFunc([]string{errEtcdLeaderChange, context.DeadlineExceeded.Error()}, func(s string) bool { + return strings.Contains(err.Error(), s) + }) + } +} diff --git a/pkg/resolution/resolver/bundle/params.go b/pkg/resolution/resolver/bundle/params.go index d410a699f7f..fddef31e498 100644 --- a/pkg/resolution/resolver/bundle/params.go +++ b/pkg/resolution/resolver/bundle/params.go @@ -21,6 +21,7 @@ import ( "github.com/google/go-containerregistry/pkg/name" pipelinev1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" + "github.com/tektoncd/pipeline/pkg/resolution/resource" ) // ParamImagePullSecret is the parameter defining what secret @@ -32,7 +33,7 @@ const ParamBundle = "bundle" // ParamName is the parameter defining what the layer name in the bundle // image is. -const ParamName = "name" +const ParamName = resource.ParamName // ParamKind is the parameter defining what the layer kind in the bundle // image is. diff --git a/pkg/resolution/resolver/framework/reconciler_test.go b/pkg/resolution/resolver/framework/reconciler_test.go index 53b3bfb7a04..e3164efed81 100644 --- a/pkg/resolution/resolver/framework/reconciler_test.go +++ b/pkg/resolution/resolver/framework/reconciler_test.go @@ -30,7 +30,7 @@ import ( "github.com/tektoncd/pipeline/pkg/apis/resolution/v1beta1" ttesting "github.com/tektoncd/pipeline/pkg/reconciler/testing" resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" - framework "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" + "github.com/tektoncd/pipeline/pkg/resolution/resolver/framework" "github.com/tektoncd/pipeline/test" "github.com/tektoncd/pipeline/test/diff" "github.com/tektoncd/pipeline/test/names" diff --git a/pkg/resolution/resolver/git/params.go b/pkg/resolution/resolver/git/params.go index 9ca9248a4f4..f1885f7c2b0 100644 --- a/pkg/resolution/resolver/git/params.go +++ b/pkg/resolution/resolver/git/params.go @@ -16,9 +16,11 @@ limitations under the License. package git +import "github.com/tektoncd/pipeline/pkg/resolution/resource" + const ( // UrlParam is the git repo Url when using the anonymous/full clone approach - UrlParam string = "url" + UrlParam string = resource.ParamURL // OrgParam is the organization to find the repository in when using the SCM API approach OrgParam = "org" // RepoParam is the repository to use when using the SCM API approach diff --git a/pkg/resolution/resolver/http/params.go b/pkg/resolution/resolver/http/params.go index d58008b5942..768832f65d8 100644 --- a/pkg/resolution/resolver/http/params.go +++ b/pkg/resolution/resolver/http/params.go @@ -13,9 +13,11 @@ limitations under the License. package http +import "github.com/tektoncd/pipeline/pkg/resolution/resource" + const ( // UrlParam is the URL to fetch the task from - UrlParam string = "url" + UrlParam string = resource.ParamURL // HttpBasicAuthUsername is the user name to use for basic auth HttpBasicAuthUsername string = "http-username" diff --git a/pkg/resolution/resolver/hub/params.go b/pkg/resolution/resolver/hub/params.go index 6c77736b48f..211ad7cda9a 100644 --- a/pkg/resolution/resolver/hub/params.go +++ b/pkg/resolution/resolver/hub/params.go @@ -13,6 +13,8 @@ limitations under the License. package hub +import "github.com/tektoncd/pipeline/pkg/resolution/resource" + // DefaultArtifactHubURL is the default url for the Artifact hub api const DefaultArtifactHubURL = "https://artifacthub.io" @@ -30,7 +32,7 @@ const ArtifactHubListTasksEndpoint = "api/v1/packages/tekton-%s/%s/%s" // ParamName is the parameter defining what the layer name in the bundle // image is. -const ParamName = "name" +const ParamName = resource.ParamName // ParamKind is the parameter defining what the layer kind in the bundle // image is. diff --git a/pkg/resolution/resource/name.go b/pkg/resolution/resource/name.go index f93e0814e2e..4e931978695 100644 --- a/pkg/resolution/resource/name.go +++ b/pkg/resolution/resource/name.go @@ -29,6 +29,16 @@ import ( "knative.dev/pkg/kmeta" ) +const ( + // ParamName is a param that explicitly assigns a name to the remote object + ParamName = "name" + + // ParamURL is a param that hold the URL used for accesing the remote object + ParamURL = "url" +) + +// + const maxLength = validation.DNS1123LabelMaxLength // GenerateDeterministicName makes a best-effort attempt to create a @@ -116,3 +126,28 @@ func GenerateDeterministicNameFromSpec(prefix, base string, resolutionSpec *v1be } return name[:strings.LastIndex(name[:maxLength], " ")], nil } + +// GenerateErrorLogString makes a best effort attempt to get the name of the task +// when a resolver error occurred. The TaskRef name does not have to be set, where +// the specific resolver gets the name from the parameters. +func GenerateErrorLogString(resolverType string, params v1.Params) string { + paramString := fmt.Sprintf("resolver type %s\n", resolverType) + for _, p := range params { + if p.Name == ParamName { + name := p.Value.StringVal + if p.Value.Type != v1.ParamTypeString { + asJSON, err := p.Value.MarshalJSON() + if err != nil { + paramString += fmt.Sprintf("name could not be marshalled: %s\n", err.Error()) + continue + } + name = string(asJSON) + } + paramString += fmt.Sprintf("name = %s\n", name) + } + if p.Name == ParamURL { + paramString += fmt.Sprintf("url = %s\n", p.Value.StringVal) + } + } + return paramString +} diff --git a/pkg/resolution/resource/name_test.go b/pkg/resolution/resource/name_test.go index 95bb8c3afe1..c80973d942d 100644 --- a/pkg/resolution/resource/name_test.go +++ b/pkg/resolution/resource/name_test.go @@ -17,6 +17,7 @@ limitations under the License. package resource_test import ( + "strings" "testing" v1 "github.com/tektoncd/pipeline/pkg/apis/pipeline/v1" @@ -218,3 +219,97 @@ func TestGenerateDeterministicNameFromSpec(t *testing.T) { }) } } + +func TestGenerateErrorLogString(t *testing.T) { + tests := []struct { + resolverType string + name string + url string + err string + params []v1.Param + isPresent bool + }{ + { + name: "foo", + url: "https://bar", + resolverType: "git", + isPresent: true, + params: []v1.Param{ + { + Name: resource.ParamName, + Value: v1.ParamValue{ + Type: v1.ParamTypeString, + StringVal: "foo", + }, + }, + { + Name: resource.ParamURL, + Value: v1.ParamValue{ + Type: v1.ParamTypeString, + StringVal: "https://bar", + }, + }, + }, + }, + { + name: "foo", + url: "https://bar", + resolverType: "", + err: "name could not be marshalled", + params: []v1.Param{}, + }, + { + name: "goo", + resolverType: "bundle", + isPresent: true, + params: []v1.Param{ + { + Name: resource.ParamName, + Value: v1.ParamValue{ + Type: v1.ParamTypeString, + StringVal: "goo", + }, + }, + }, + }, + { + name: "hoo", + resolverType: "cluster", + err: "name could not be marshalled", + isPresent: true, + params: []v1.Param{ + { + Name: resource.ParamName, + Value: v1.ParamValue{ + Type: v1.ParamTypeString, + StringVal: "hoo", + }, + }, + { + Name: resource.ParamName, + Value: v1.ParamValue{ + Type: v1.ParamType("foo"), + }, + }, + }, + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + got := resource.GenerateErrorLogString(tt.resolverType, tt.params) + if strings.Contains(got, tt.name) != tt.isPresent { + t.Errorf("name %s presence in %s should be %v", tt.name, got, tt.isPresent) + } + if strings.Contains(got, tt.url) != tt.isPresent { + t.Errorf("url %s presence in %s should be %v", tt.url, got, tt.isPresent) + } + if strings.Contains(got, tt.err) != tt.isPresent { + t.Errorf("err %s presence in %s should be %v", tt.err, got, tt.isPresent) + } + // should always have resolver type + if !strings.Contains(got, tt.resolverType) { + t.Errorf("type %s not in %s", tt.resolverType, got) + } + }) + } +} From 1b74ff31ebd293763cc12d6549e8206e854b2743 Mon Sep 17 00:00:00 2001 From: Chitrang Patel Date: Mon, 6 May 2024 11:44:13 -0400 Subject: [PATCH 21/23] Propagate params in pipelines Prior to this, we allowed parameter propagation in an inlined pipelinerun. However, within a pipeline, we requrie a verbose spec. This was an oversight as indicated in https://github.com/tektoncd/pipeline/issues/7901. This PR fixes that issue by updating the validation logic in the webhook. Fixes https://github.com/tektoncd/pipeline/issues/7901. Propagate params in pipelines Prior to this, we allowed parameter propagation in an inlined pipelinerun. However, within a pipeline, we requrie a verbose spec. This was an oversight as indicated in https://github.com/tektoncd/pipeline/issues/7901. This PR fixes that issue by updating the validation logic in the webhook. Fixes https://github.com/tektoncd/pipeline/issues/7901. --- docs/pipelines.md | 39 ++++++ .../propagating-workspaces-in-pipelines.yaml | 32 +++++ .../propagating_params_in_pipeline.yaml | 37 +++++ pkg/apis/pipeline/v1/pipeline_validation.go | 8 +- .../pipeline/v1/pipeline_validation_test.go | 131 ++++++++++++++++++ .../pipeline/v1beta1/pipeline_validation.go | 8 +- .../v1beta1/pipeline_validation_test.go | 131 ++++++++++++++++++ 7 files changed, 378 insertions(+), 8 deletions(-) create mode 100644 examples/v1/pipelineruns/propagating-workspaces-in-pipelines.yaml create mode 100644 examples/v1/pipelineruns/propagating_params_in_pipeline.yaml diff --git a/docs/pipelines.md b/docs/pipelines.md index ebc0b2f9b0b..e2febbea326 100644 --- a/docs/pipelines.md +++ b/docs/pipelines.md @@ -369,6 +369,45 @@ any resolved `param` value against the `enum` specified in each `PipelineTask` b See usage in this [example](../examples/v1/pipelineruns/alpha/param-enum.yaml) +#### Propagated Params + +Like with embedded [pipelineruns](pipelineruns.md#propagated-parameters), you can propagate `params` declared in the `pipeline` down to the inlined `pipelineTasks` and its inlined `Steps`. Wherever a resource (e.g. a `pipelineTask`) or a `StepAction` is referenced, the parameters need to be passed explicitly. + +For example, the following is a valid yaml. + +```yaml +apiVersion: tekton.dev/v1 # or tekton.dev/v1beta1 +kind: Pipeline +metadata: + name: pipelien-propagated-params +spec: + params: + - name: HELLO + default: "Hello World!" + - name: BYE + default: "Bye World!" + tasks: + - name: echo-hello + taskSpec: + steps: + - name: echo + image: ubuntu + script: | + #!/usr/bin/env bash + echo "$(params.HELLO)" + - name: echo-bye + taskSpec: + steps: + - name: echo-action + ref: + name: step-action-echo + params: + - name: msg + value: "$(params.BYE)" +``` +The same rules defined in [pipelineruns](pipelineruns.md#propagated-parameters) apply here. + + ## Adding `Tasks` to the `Pipeline` Your `Pipeline` definition must reference at least one [`Task`](tasks.md). diff --git a/examples/v1/pipelineruns/propagating-workspaces-in-pipelines.yaml b/examples/v1/pipelineruns/propagating-workspaces-in-pipelines.yaml new file mode 100644 index 00000000000..b8bcd0b5859 --- /dev/null +++ b/examples/v1/pipelineruns/propagating-workspaces-in-pipelines.yaml @@ -0,0 +1,32 @@ +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: workspace-example +spec: + workspaces: + - name: shared-data + tasks: + - name: t1 + taskSpec: + steps: + - image: ubuntu + command: ["ls"] + args: ["$(workspaces.shared-data.path)"] +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + name: workspace-example-run +spec: + pipelineRef: + name: workspace-example + workspaces: + - name: shared-data + volumeClaimTemplate: + spec: + accessModes: + - ReadWriteOnce + resources: + requests: + storage: 16Mi + volumeMode: Filesystem diff --git a/examples/v1/pipelineruns/propagating_params_in_pipeline.yaml b/examples/v1/pipelineruns/propagating_params_in_pipeline.yaml new file mode 100644 index 00000000000..ce60256c66f --- /dev/null +++ b/examples/v1/pipelineruns/propagating_params_in_pipeline.yaml @@ -0,0 +1,37 @@ +apiVersion: tekton.dev/v1 +kind: Pipeline +metadata: + name: propagating-params-in-pipeline +spec: + params: + - name: HELLO + default: "Pipeline Hello World!" + tasks: + - name: echo-hello + taskSpec: + steps: + - name: echo + image: ubuntu + script: | + #!/usr/bin/env bash + echo "$(params.HELLO)" + finally: + - name: echo-hello-finally + taskSpec: + steps: + - name: echo + image: ubuntu + script: | + #!/usr/bin/env bash + echo "And Finally ... $(params.HELLO)" +--- +apiVersion: tekton.dev/v1 +kind: PipelineRun +metadata: + generateName: propagating-params-in-pipeline- +spec: + params: + - name: HELLO + value: "Hello from pipeline run" + pipelineRef: + name: propagating-params-in-pipeline \ No newline at end of file diff --git a/pkg/apis/pipeline/v1/pipeline_validation.go b/pkg/apis/pipeline/v1/pipeline_validation.go index a0b65f7787c..43e56d102f5 100644 --- a/pkg/apis/pipeline/v1/pipeline_validation.go +++ b/pkg/apis/pipeline/v1/pipeline_validation.go @@ -151,10 +151,10 @@ func (l PipelineTaskList) Validate(ctx context.Context, taskNames sets.String, p } // validateUsageOfDeclaredPipelineTaskParameters validates that all parameters referenced in the pipeline Task are declared by the pipeline Task. -func (l PipelineTaskList) validateUsageOfDeclaredPipelineTaskParameters(ctx context.Context, path string) (errs *apis.FieldError) { +func (l PipelineTaskList) validateUsageOfDeclaredPipelineTaskParameters(ctx context.Context, additionalParams []ParamSpec, path string) (errs *apis.FieldError) { for i, t := range l { if t.TaskSpec != nil { - errs = errs.Also(ValidateUsageOfDeclaredParameters(ctx, t.TaskSpec.Steps, t.TaskSpec.Params).ViaFieldIndex(path, i)) + errs = errs.Also(ValidateUsageOfDeclaredParameters(ctx, t.TaskSpec.Steps, append(t.TaskSpec.Params, additionalParams...)).ViaFieldIndex(path, i)) } } return errs @@ -385,8 +385,8 @@ func validatePipelineWorkspacesDeclarations(wss []PipelineWorkspaceDeclaration) // validatePipelineParameterUsage validates that parameters referenced in the Pipeline are declared by the Pipeline func (ps *PipelineSpec) validatePipelineParameterUsage(ctx context.Context) (errs *apis.FieldError) { - errs = errs.Also(PipelineTaskList(ps.Tasks).validateUsageOfDeclaredPipelineTaskParameters(ctx, "tasks")) - errs = errs.Also(PipelineTaskList(ps.Finally).validateUsageOfDeclaredPipelineTaskParameters(ctx, "finally")) + errs = errs.Also(PipelineTaskList(ps.Tasks).validateUsageOfDeclaredPipelineTaskParameters(ctx, ps.Params, "tasks")) + errs = errs.Also(PipelineTaskList(ps.Finally).validateUsageOfDeclaredPipelineTaskParameters(ctx, ps.Params, "finally")) errs = errs.Also(validatePipelineTaskParameterUsage(ps.Tasks, ps.Params).ViaField("tasks")) errs = errs.Also(validatePipelineTaskParameterUsage(ps.Finally, ps.Params).ViaField("finally")) return errs diff --git a/pkg/apis/pipeline/v1/pipeline_validation_test.go b/pkg/apis/pipeline/v1/pipeline_validation_test.go index 446c8177066..236283d2630 100644 --- a/pkg/apis/pipeline/v1/pipeline_validation_test.go +++ b/pkg/apis/pipeline/v1/pipeline_validation_test.go @@ -114,6 +114,65 @@ func TestPipeline_Validate_Success(t *testing.T) { }, }, }, + }, { + name: "propagating params into Step", + p: &Pipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipelinelinename", + }, + Spec: PipelineSpec{ + Params: ParamSpecs{{ + Name: "pipeline-words", + Type: ParamTypeArray, + Default: &ParamValue{ + Type: ParamTypeArray, + ArrayVal: []string{"hello", "pipeline"}, + }, + }}, + Tasks: []PipelineTask{{ + Name: "echoit", + TaskSpec: &EmbeddedTask{TaskSpec: TaskSpec{ + Steps: []Step{{ + Name: "echo", + Image: "ubuntu", + Command: []string{"echo"}, + Args: []string{"$(params.pipeline-words[*])"}, + }}, + }}, + }}, + }, + }, + }, { + name: "propagating object params with pipelinespec and taskspec", + p: &Pipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipelinelinename", + }, + Spec: PipelineSpec{ + Params: ParamSpecs{{ + Name: "pipeline-words", + Default: &ParamValue{ + Type: ParamTypeObject, + ObjectVal: map[string]string{"hello": "pipeline"}, + }, + Type: ParamTypeObject, + Properties: map[string]PropertySpec{ + "hello": {Type: ParamTypeString}, + }, + }}, + Tasks: []PipelineTask{{ + Name: "echoit", + TaskSpec: &EmbeddedTask{TaskSpec: TaskSpec{ + Steps: []Step{{ + Name: "echo", + Image: "ubuntu", + Command: []string{"echo"}, + Args: []string{"$(params.pipeline-words.hello)"}, + }}, + }}, + }}, + }, + }, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -365,6 +424,78 @@ func TestPipeline_Validate_Failure(t *testing.T) { }, }) }, + }, { + name: "propagating params with pipelinespec and taskspec", + p: &Pipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipelinename", + }, + Spec: PipelineSpec{ + Params: ParamSpecs{{ + Name: "pipeline-words", + Type: ParamTypeArray, + Default: &ParamValue{ + Type: ParamTypeArray, + ArrayVal: []string{"hello", "pipeline"}, + }, + }}, + Tasks: []PipelineTask{{ + Name: "echoit", + TaskSpec: &EmbeddedTask{TaskSpec: TaskSpec{ + Steps: []Step{{ + Name: "echo", + Image: "ubuntu", + Command: []string{"echo"}, + Args: []string{"$(params.random-words[*])"}, + }}, + }}, + }}, + }, + }, + expectedError: apis.FieldError{ + Message: `non-existent variable in "$(params.random-words[*])"`, + Paths: []string{"spec.tasks[0].steps[0].args[0]"}, + }, + }, { + name: "propagating params to taskRef", + p: &Pipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipelinename", + }, + Spec: PipelineSpec{ + Params: ParamSpecs{{ + Name: "hello", + Type: ParamTypeString, + Default: &ParamValue{ + Type: ParamTypeString, + StringVal: "hi", + }, + }}, + Tasks: []PipelineTask{{ + Name: "echoit", + TaskRef: &TaskRef{ + Name: "remote-task", + }, + Params: Params{{ + Name: "param1", + Value: ParamValue{ + Type: ParamTypeString, + StringVal: "$(params.param1)", + }, + }, { + Name: "holla", + Value: ParamValue{ + Type: ParamTypeString, + StringVal: "$(params.hello)", + }, + }}, + }}, + }, + }, + expectedError: apis.FieldError{ + Message: `non-existent variable in "$(params.param1)"`, + Paths: []string{"spec.tasks[0].params[param1]"}, + }, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { diff --git a/pkg/apis/pipeline/v1beta1/pipeline_validation.go b/pkg/apis/pipeline/v1beta1/pipeline_validation.go index f1c34eee5e5..0a5f2ec3804 100644 --- a/pkg/apis/pipeline/v1beta1/pipeline_validation.go +++ b/pkg/apis/pipeline/v1beta1/pipeline_validation.go @@ -153,10 +153,10 @@ func (l PipelineTaskList) Validate(ctx context.Context, taskNames sets.String, p } // validateUsageOfDeclaredPipelineTaskParameters validates that all parameters referenced in the pipeline Task are declared by the pipeline Task. -func (l PipelineTaskList) validateUsageOfDeclaredPipelineTaskParameters(ctx context.Context, path string) (errs *apis.FieldError) { +func (l PipelineTaskList) validateUsageOfDeclaredPipelineTaskParameters(ctx context.Context, additionalParams []ParamSpec, path string) (errs *apis.FieldError) { for i, t := range l { if t.TaskSpec != nil { - errs = errs.Also(ValidateUsageOfDeclaredParameters(ctx, t.TaskSpec.Steps, t.TaskSpec.Params).ViaFieldIndex(path, i)) + errs = errs.Also(ValidateUsageOfDeclaredParameters(ctx, t.TaskSpec.Steps, append(t.TaskSpec.Params, additionalParams...)).ViaFieldIndex(path, i)) } } return errs @@ -403,8 +403,8 @@ func validatePipelineWorkspacesDeclarations(wss []PipelineWorkspaceDeclaration) // validatePipelineParameterUsage validates that parameters referenced in the Pipeline are declared by the Pipeline func (ps *PipelineSpec) validatePipelineParameterUsage(ctx context.Context) (errs *apis.FieldError) { - errs = errs.Also(PipelineTaskList(ps.Tasks).validateUsageOfDeclaredPipelineTaskParameters(ctx, "tasks")) - errs = errs.Also(PipelineTaskList(ps.Finally).validateUsageOfDeclaredPipelineTaskParameters(ctx, "finally")) + errs = errs.Also(PipelineTaskList(ps.Tasks).validateUsageOfDeclaredPipelineTaskParameters(ctx, ps.Params, "tasks")) + errs = errs.Also(PipelineTaskList(ps.Finally).validateUsageOfDeclaredPipelineTaskParameters(ctx, ps.Params, "finally")) errs = errs.Also(validatePipelineTaskParameterUsage(ps.Tasks, ps.Params).ViaField("tasks")) errs = errs.Also(validatePipelineTaskParameterUsage(ps.Finally, ps.Params).ViaField("finally")) return errs diff --git a/pkg/apis/pipeline/v1beta1/pipeline_validation_test.go b/pkg/apis/pipeline/v1beta1/pipeline_validation_test.go index adb5810009b..0774662563e 100644 --- a/pkg/apis/pipeline/v1beta1/pipeline_validation_test.go +++ b/pkg/apis/pipeline/v1beta1/pipeline_validation_test.go @@ -116,6 +116,65 @@ func TestPipeline_Validate_Success(t *testing.T) { }, }, }, + }, { + name: "propagating params into Step", + p: &Pipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipelinelinename", + }, + Spec: PipelineSpec{ + Params: ParamSpecs{{ + Name: "pipeline-words", + Type: ParamTypeArray, + Default: &ParamValue{ + Type: ParamTypeArray, + ArrayVal: []string{"hello", "pipeline"}, + }, + }}, + Tasks: []PipelineTask{{ + Name: "echoit", + TaskSpec: &EmbeddedTask{TaskSpec: TaskSpec{ + Steps: []Step{{ + Name: "echo", + Image: "ubuntu", + Command: []string{"echo"}, + Args: []string{"$(params.pipeline-words[*])"}, + }}, + }}, + }}, + }, + }, + }, { + name: "propagating object params with pipelinespec and taskspec", + p: &Pipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipelinelinename", + }, + Spec: PipelineSpec{ + Params: ParamSpecs{{ + Name: "pipeline-words", + Default: &ParamValue{ + Type: ParamTypeObject, + ObjectVal: map[string]string{"hello": "pipeline"}, + }, + Type: ParamTypeObject, + Properties: map[string]PropertySpec{ + "hello": {Type: ParamTypeString}, + }, + }}, + Tasks: []PipelineTask{{ + Name: "echoit", + TaskSpec: &EmbeddedTask{TaskSpec: TaskSpec{ + Steps: []Step{{ + Name: "echo", + Image: "ubuntu", + Command: []string{"echo"}, + Args: []string{"$(params.pipeline-words.hello)"}, + }}, + }}, + }}, + }, + }, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { @@ -367,6 +426,78 @@ func TestPipeline_Validate_Failure(t *testing.T) { }, }) }, + }, { + name: "propagating params with pipelinespec and taskspec", + p: &Pipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipelinename", + }, + Spec: PipelineSpec{ + Params: ParamSpecs{{ + Name: "pipeline-words", + Type: ParamTypeArray, + Default: &ParamValue{ + Type: ParamTypeArray, + ArrayVal: []string{"hello", "pipeline"}, + }, + }}, + Tasks: []PipelineTask{{ + Name: "echoit", + TaskSpec: &EmbeddedTask{TaskSpec: TaskSpec{ + Steps: []Step{{ + Name: "echo", + Image: "ubuntu", + Command: []string{"echo"}, + Args: []string{"$(params.random-words[*])"}, + }}, + }}, + }}, + }, + }, + expectedError: apis.FieldError{ + Message: `non-existent variable in "$(params.random-words[*])"`, + Paths: []string{"spec.tasks[0].steps[0].args[0]"}, + }, + }, { + name: "propagating params to taskRef", + p: &Pipeline{ + ObjectMeta: metav1.ObjectMeta{ + Name: "pipelinename", + }, + Spec: PipelineSpec{ + Params: ParamSpecs{{ + Name: "hello", + Type: ParamTypeString, + Default: &ParamValue{ + Type: ParamTypeString, + StringVal: "hi", + }, + }}, + Tasks: []PipelineTask{{ + Name: "echoit", + TaskRef: &TaskRef{ + Name: "remote-task", + }, + Params: Params{{ + Name: "param1", + Value: ParamValue{ + Type: ParamTypeString, + StringVal: "$(params.param1)", + }, + }, { + Name: "holla", + Value: ParamValue{ + Type: ParamTypeString, + StringVal: "$(params.hello)", + }, + }}, + }}, + }, + }, + expectedError: apis.FieldError{ + Message: `non-existent variable in "$(params.param1)"`, + Paths: []string{"spec.tasks[0].params[param1]"}, + }, }} for _, tt := range tests { t.Run(tt.name, func(t *testing.T) { From 3dab35e138c74663f03331ed3c0fac97753135f8 Mon Sep 17 00:00:00 2001 From: gabemontero Date: Thu, 16 May 2024 12:32:39 -0400 Subject: [PATCH 22/23] minor followup to PR 7894 - add comment on why we check param when generating error log - add unit test that covers getting name from non-string param type rh-pre-commit.version: 2.2.0 rh-pre-commit.check-secrets: ENABLED --- .../pipelinerun/resources/pipelinerunresolution.go | 2 ++ pkg/resolution/resource/name_test.go | 14 ++++++++++++++ 2 files changed, 16 insertions(+) diff --git a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go index 6f78d31ba4d..182a347a10c 100644 --- a/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go +++ b/pkg/reconciler/pipelinerun/resources/pipelinerunresolution.go @@ -646,6 +646,8 @@ func resolveTask( case errors.Is(err, remote.ErrRequestInProgress): return rt, err case err != nil: + // some of the resolvers obtain the name from the parameters instead of from the TaskRef.Name field, + // so we account for both locations when constructing the error name := pipelineTask.TaskRef.Name if len(strings.TrimSpace(name)) == 0 { name = resource.GenerateErrorLogString(string(pipelineTask.TaskRef.Resolver), pipelineTask.TaskRef.Params) diff --git a/pkg/resolution/resource/name_test.go b/pkg/resolution/resource/name_test.go index c80973d942d..738d84cc47d 100644 --- a/pkg/resolution/resource/name_test.go +++ b/pkg/resolution/resource/name_test.go @@ -272,6 +272,20 @@ func TestGenerateErrorLogString(t *testing.T) { }, }, }, + { + name: "goo-array", + resolverType: "bundle", + isPresent: true, + params: []v1.Param{ + { + Name: resource.ParamName, + Value: v1.ParamValue{ + Type: v1.ParamTypeArray, + ArrayVal: []string{resource.ParamName, "goo-array"}, + }, + }, + }, + }, { name: "hoo", resolverType: "cluster", From 45737535d148d5af1157c8a5c16166eecab2d6ed Mon Sep 17 00:00:00 2001 From: Chitrang Patel Date: Thu, 16 May 2024 16:08:46 -0400 Subject: [PATCH 23/23] Fix: Faulty Remote Resource Accepted by Remote Resolution This PR fixes the issue where a bad remote resource is accepted by remote resolution. --- pkg/remote/resolution/resolver.go | 4 +- pkg/remote/resolution/resolver_test.go | 71 ++++++++++++++++++++++++++ 2 files changed, 74 insertions(+), 1 deletion(-) diff --git a/pkg/remote/resolution/resolver.go b/pkg/remote/resolution/resolver.go index fb164924f03..eb56ab04d2f 100644 --- a/pkg/remote/resolution/resolver.go +++ b/pkg/remote/resolution/resolver.go @@ -24,6 +24,7 @@ import ( resolutioncommon "github.com/tektoncd/pipeline/pkg/resolution/common" remoteresource "github.com/tektoncd/pipeline/pkg/resolution/resource" "k8s.io/apimachinery/pkg/runtime" + "k8s.io/apimachinery/pkg/runtime/serializer" "knative.dev/pkg/kmeta" ) @@ -97,7 +98,8 @@ func ResolvedRequest(resolved resolutioncommon.ResolvedResource, err error) (run if err != nil { return nil, nil, &DataAccessError{Original: err} } - obj, _, err := scheme.Codecs.UniversalDeserializer().Decode(data, nil, nil) + codecs := serializer.NewCodecFactory(scheme.Scheme, serializer.EnableStrict) + obj, _, err := codecs.UniversalDeserializer().Decode(data, nil, nil) if err != nil { return nil, nil, &InvalidRuntimeObjectError{Original: err} } diff --git a/pkg/remote/resolution/resolver_test.go b/pkg/remote/resolution/resolver_test.go index 6f078ac2851..eeb4a158333 100644 --- a/pkg/remote/resolution/resolver_test.go +++ b/pkg/remote/resolution/resolver_test.go @@ -75,6 +75,50 @@ func TestGet_Successful(t *testing.T) { } } +var invalidPipelineBytes = []byte(` +kind: Pipeline +apiVersion: tekton.dev/v1 +metadata: + name: foo +spec: + tasks: + - name: task1 + taskSpec: + foo: bar + steps: + - name: step1 + image: ubuntu + script: | + echo "hello world!" + foo: bar +`) + +var invalidTaskBytes = []byte(` +kind: Task +apiVersion: tekton.dev/v1 +metadata: + name: foo +spec: + foo: bar + steps: + - name: step1 + image: ubuntu + script: | + echo "hello world!" +`) + +var invalidStepActionBytes = []byte(` +kind: StepAction +apiVersion: tekton.dev/v1beta1 +metadata: + name: foo +spec: + image: ubuntu + script: | + echo "hello world!" + foo: bar +`) + func TestGet_Errors(t *testing.T) { genericError := errors.New("uh oh something bad happened") notARuntimeObject := &resolution.ResolvedResource{ @@ -85,6 +129,21 @@ func TestGet_Errors(t *testing.T) { DataErr: errors.New("data access error"), ResolvedAnnotations: nil, } + invalidPipeline := &resolution.ResolvedResource{ + ResolvedData: invalidPipelineBytes, + DataErr: errors.New(`spec.tasks[0].taskSpec.foo", unknown field "spec.tasks[0].taskSpec.steps[0].foo`), + ResolvedAnnotations: nil, + } + invalidTask := &resolution.ResolvedResource{ + ResolvedData: invalidTaskBytes, + DataErr: errors.New(`spec.foo", unknown field "spec.steps[0].foo`), + ResolvedAnnotations: nil, + } + invalidStepAction := &resolution.ResolvedResource{ + ResolvedData: invalidStepActionBytes, + DataErr: errors.New(`unknown field "spec.foo`), + ResolvedAnnotations: nil, + } for _, tc := range []struct { submitErr error expectedGetErr error @@ -109,6 +168,18 @@ func TestGet_Errors(t *testing.T) { submitErr: nil, expectedGetErr: &DataAccessError{}, resolvedResource: invalidDataResource, + }, { + submitErr: nil, + expectedGetErr: &DataAccessError{}, + resolvedResource: invalidPipeline, + }, { + submitErr: nil, + expectedGetErr: &DataAccessError{}, + resolvedResource: invalidTask, + }, { + submitErr: nil, + expectedGetErr: &DataAccessError{}, + resolvedResource: invalidStepAction, }} { ctx := context.Background() owner := &v1beta1.PipelineRun{