From c337a74cb79c2682f274f232e6cd4583528f329e Mon Sep 17 00:00:00 2001 From: Alan Clucas Date: Wed, 2 Jul 2025 16:09:58 +0100 Subject: [PATCH 1/2] feat: artifact plugins Signed-off-by: Alan Clucas --- .features/pending/artifact-plugins.md | 8 + .spelling | 2 + Makefile | 13 +- README.md | 2 +- api/jsonschema/schema.json | 62 + api/openapi-spec/swagger.json | 62 + cmd/argoexec/commands/artifact/delete.go | 27 +- cmd/argoexec/commands/artifact_plugin_init.go | 80 + .../commands/artifact_plugin_sidecar.go | 110 + cmd/argoexec/commands/emissary.go | 10 +- cmd/argoexec/commands/init.go | 2 +- cmd/argoexec/commands/root.go | 2 + cmd/argoexec/commands/wait.go | 33 +- config/config.go | 32 + docs/README.md | 2 +- docs/artifact-plugin.md | 314 ++ docs/configure-artifact-repository.md | 199 +- docs/executor_swagger.md | 38 + docs/fields.md | 67 + docs/plugins.md | 6 + docs/workflow-controller-configmap.md | 12 + .../artifact-passing-explicit-plugin.yaml | 52 + hack/docs/configdoc.go | 6 + .../argoproj.io_clusterworkflowtemplates.yaml | 552 +++ .../crds/full/argoproj.io_cronworkflows.yaml | 566 +++ .../argoproj.io_workflowartifactgctasks.yaml | 53 + .../argoproj.io_workfloweventbindings.yaml | 27 + .../base/crds/full/argoproj.io_workflows.yaml | 972 ++++ .../full/argoproj.io_workflowtaskresults.yaml | 24 + .../full/argoproj.io_workflowtasksets.yaml | 280 ++ .../full/argoproj.io_workflowtemplates.yaml | 552 +++ .../argoproj.io_workflowartifactgctasks.yaml | 53 + .../argoproj.io_workfloweventbindings.yaml | 27 + .../argoproj.io_workflowtaskresults.yaml | 24 + manifests/quick-start-minimal.yaml | 143 +- manifests/quick-start-mysql.yaml | 143 +- manifests/quick-start-postgres.yaml | 143 +- .../base/artifact-repositories-configmap.yaml | 14 + .../workflow-controller-configmap.yaml | 23 +- .../quick-start/base/pod-manager-role.yaml | 2 + mkdocs.yml | 4 +- pkg/apiclient/artifact/artifact.pb.go | 4049 +++++++++++++++++ pkg/apiclient/artifact/artifact.pb.gw.go | 549 +++ pkg/apiclient/artifact/artifact.proto | 132 + pkg/apiclient/artifact/artifact.swagger.json | 460 ++ .../v1alpha1/artifact_plugins_test.go | 945 ++++ .../v1alpha1/artifact_repository_types.go | 21 +- .../artifact_repository_types_test.go | 7 + pkg/apis/workflow/v1alpha1/generated.pb.go | 2159 +++++---- pkg/apis/workflow/v1alpha1/generated.proto | 30 + .../workflow/v1alpha1/openapi_generated.go | 113 +- pkg/apis/workflow/v1alpha1/workflow_types.go | 133 + .../workflow/v1alpha1/workflow_types_test.go | 5 + .../v1alpha1/zz_generated.deepcopy.go | 42 + pkg/plugins/executor/swagger.yml | 25 + .../IoArgoprojWorkflowV1alpha1Artifact.md | 1 + ...rgoprojWorkflowV1alpha1ArtifactLocation.md | 1 + ...IoArgoprojWorkflowV1alpha1ArtifactPaths.md | 1 + ...oprojWorkflowV1alpha1ArtifactRepository.md | 1 + ...oArgoprojWorkflowV1alpha1PluginArtifact.md | 17 + ...orkflowV1alpha1PluginArtifactRepository.md | 16 + .../io_argoproj_workflow_v1alpha1_artifact.py | 6 + ...roj_workflow_v1alpha1_artifact_location.py | 6 + ...goproj_workflow_v1alpha1_artifact_paths.py | 6 + ...j_workflow_v1alpha1_artifact_repository.py | 6 + ...oproj_workflow_v1alpha1_plugin_artifact.py | 277 ++ ...low_v1alpha1_plugin_artifact_repository.py | 271 ++ .../client/argo_workflows/models/__init__.py | 2 + .../docs/ClusterWorkflowTemplateServiceApi.md | 360 ++ .../client/docs/CronWorkflowServiceApi.md | 360 ++ .../IoArgoprojWorkflowV1alpha1Artifact.md | 1 + ...rgoprojWorkflowV1alpha1ArtifactLocation.md | 1 + ...IoArgoprojWorkflowV1alpha1ArtifactPaths.md | 1 + ...oprojWorkflowV1alpha1ArtifactRepository.md | 1 + ...oArgoprojWorkflowV1alpha1PluginArtifact.md | 16 + ...orkflowV1alpha1PluginArtifactRepository.md | 15 + sdks/python/client/docs/WorkflowServiceApi.md | 634 +++ .../client/docs/WorkflowTemplateServiceApi.md | 360 ++ server/apiserver/argoserver.go | 134 +- server/apiserver/argoserver_test.go | 233 + server/artifacts/artifact_server.go | 8 +- test/e2e/artifacts_test.go | 603 ++- .../timeouts-step-plugin.yaml | 20 + test/e2e/fixtures/then.go | 5 + .../components/base/minio-deployment.yaml | 4 +- .../base/workflow-controller-configmap.yaml | 5 +- .../artifact-passing-plugin-workflow.yaml | 41 + ...gc-artifact-not-written-failed-plugin.yaml | 40 + .../artgc-dag-wf-self-delete-plugin.yaml | 104 + .../artgc-from-ref-template-plugin.yaml | 8 + .../artgc-from-template-2-plugin.yaml | 8 + .../artgc-from-template-plugin.yaml | 8 + ...rtgc-multi-strategy-multi-anno-plugin.yaml | 141 + ...-optional-artifact-not-written-plugin.yaml | 79 + ...-optional-artifact-not-written-plugin.yaml | 80 + .../artgc-step-wf-tmpl-2-plugin.yaml | 14 + .../artgc-step-wf-tmpl-no-gc-plugin.yaml | 16 + .../artifactgc/artgc-step-wf-tmpl-plugin.yaml | 14 + .../artifactgc/artgc-template-2-plugin.yaml | 60 + .../artgc-template-no-gc-plugin.yaml | 62 + .../artifactgc/artgc-template-plugin.yaml | 60 + .../artgc-template-ref-template-plugin.yaml | 16 + ...omplex-global-artifact-passing-plugin.yaml | 209 + .../default-params-plugin-workflow.yaml | 43 + .../global-artifact-passing-plugin.yaml | 96 + .../input-on-mount-plugin-workflow.yaml | 44 + .../testdata/main-log-plugin-workflow.yaml | 16 + .../output-on-input-plugin-workflow.yaml | 27 + .../output-on-mount-plugin-workflow.yaml | 26 + ...ame-input-output-path-optional-plugin.yaml | 23 + util/k8s/pod.go | 46 + util/k8s/pod_test.go | 87 + workflow/artifacts/artifacts.go | 14 +- workflow/artifacts/artifacts_test.go | 2 +- workflow/artifacts/plugin/plugin.go | 287 ++ workflow/artifacts/plugin/plugin_test.go | 101 + workflow/common/common.go | 24 +- workflow/controller/artifact_gc.go | 103 +- workflow/controller/artifact_gc_test.go | 196 + workflow/controller/controller.go | 1 - workflow/controller/workflowpod.go | 216 +- workflow/controller/workflowpod_test.go | 307 ++ workflow/executor/emissary/emissary.go | 22 +- workflow/executor/executor.go | 47 +- workflow/executor/executor_test.go | 2 +- 125 files changed, 18447 insertions(+), 1028 deletions(-) create mode 100644 .features/pending/artifact-plugins.md create mode 100644 cmd/argoexec/commands/artifact_plugin_init.go create mode 100644 cmd/argoexec/commands/artifact_plugin_sidecar.go create mode 100644 docs/artifact-plugin.md create mode 100644 examples/artifact-passing-explicit-plugin.yaml create mode 100644 pkg/apiclient/artifact/artifact.pb.go create mode 100644 pkg/apiclient/artifact/artifact.pb.gw.go create mode 100644 pkg/apiclient/artifact/artifact.proto create mode 100644 pkg/apiclient/artifact/artifact.swagger.json create mode 100644 pkg/apis/workflow/v1alpha1/artifact_plugins_test.go create mode 100644 sdks/java/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifact.md create mode 100644 sdks/java/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifactRepository.md create mode 100644 sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_plugin_artifact.py create mode 100644 sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_plugin_artifact_repository.py create mode 100644 sdks/python/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifact.md create mode 100644 sdks/python/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifactRepository.md create mode 100644 server/apiserver/argoserver_test.go create mode 100644 test/e2e/expectedfailures/timeouts-step-plugin.yaml create mode 100644 test/e2e/testdata/artifact-passing-plugin-workflow.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-artifact-not-written-failed-plugin.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-dag-wf-self-delete-plugin.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-from-ref-template-plugin.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-from-template-2-plugin.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-from-template-plugin.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-multi-strategy-multi-anno-plugin.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-non-optional-artifact-not-written-plugin.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-optional-artifact-not-written-plugin.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-step-wf-tmpl-2-plugin.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-step-wf-tmpl-no-gc-plugin.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-step-wf-tmpl-plugin.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-template-2-plugin.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-template-no-gc-plugin.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-template-plugin.yaml create mode 100644 test/e2e/testdata/artifactgc/artgc-template-ref-template-plugin.yaml create mode 100644 test/e2e/testdata/complex-global-artifact-passing-plugin.yaml create mode 100644 test/e2e/testdata/default-params-plugin-workflow.yaml create mode 100644 test/e2e/testdata/global-artifact-passing-plugin.yaml create mode 100644 test/e2e/testdata/input-on-mount-plugin-workflow.yaml create mode 100644 test/e2e/testdata/main-log-plugin-workflow.yaml create mode 100644 test/e2e/testdata/output-on-input-plugin-workflow.yaml create mode 100644 test/e2e/testdata/output-on-mount-plugin-workflow.yaml create mode 100644 test/e2e/testdata/same-input-output-path-optional-plugin.yaml create mode 100644 util/k8s/pod.go create mode 100644 util/k8s/pod_test.go create mode 100644 workflow/artifacts/plugin/plugin.go create mode 100644 workflow/artifacts/plugin/plugin_test.go diff --git a/.features/pending/artifact-plugins.md b/.features/pending/artifact-plugins.md new file mode 100644 index 000000000000..5f9ccd9e0527 --- /dev/null +++ b/.features/pending/artifact-plugins.md @@ -0,0 +1,8 @@ +Description: Artifact Drivers as plugins +Author: [Alan Clucas](https://github.com/Joibel), [JP Zivalich](https://github.com/JPZ13), [Elliot Gunton](https://github.com/elliotgunton) +Component: General +Issues: 5862 + +Artifact Drivers can now be added via a plugin mechanism. +You can write a GRPC server which acts as an artifact driver to upload and download artifacts to a repository, and supply that as a docker image. +Argo workflows can then use that as a driver. diff --git a/.spelling b/.spelling index ca6942c81ee8..e82b35559d21 100644 --- a/.spelling +++ b/.spelling @@ -96,6 +96,7 @@ MySQL Nagal Nano Nginx +Node.JS Node.JS. OAuth OAuth2 @@ -272,6 +273,7 @@ v3.6.1 v3.6.5 v3.7 v3.7.0 +v4.0 validator vendored versioned diff --git a/Makefile b/Makefile index 974ddd16b7c5..32db96682389 100644 --- a/Makefile +++ b/Makefile @@ -223,7 +223,7 @@ define protoc --grpc-gateway_out=logtostderr=true:$(GOPATH)/src \ --swagger_out=logtostderr=true,fqn_for_swagger_name=true:. \ $(1) - perl -i -pe 's|argoproj/argo-workflows/|argoproj/argo-workflows/v3/|g' `echo "$(1)" | sed 's/proto/pb.go/g'` + perl -i -pe 's|argoproj/argo-workflows/|argoproj/argo-workflows/v3/|g' `echo "$(1)" | sed 's/proto/pb.go/g'` endef @@ -446,6 +446,8 @@ pkg/apis/workflow/v1alpha1/generated.proto: $(TOOL_GO_TO_PROTOBUF) $(PROTO_BINAR [ -e ./v3 ] || ln -s . v3 # Format proto files. Formatting changes generated code, so we do it here, rather that at lint time. # Why clang-format? Google uses it. + @echo "*** This will fail if your code has compilation errors, without reporting those as the cause." + @echo "*** So fix them first." find pkg/apiclient -name '*.proto'|xargs clang-format -i $(TOOL_GO_TO_PROTOBUF) \ --go-header-file=./hack/custom-boilerplate.go.txt \ @@ -454,7 +456,7 @@ pkg/apis/workflow/v1alpha1/generated.proto: $(TOOL_GO_TO_PROTOBUF) $(PROTO_BINAR --proto-import $(GOPATH)/src # Delete the link [ -e ./v3 ] && rm -rf v3 - touch pkg/apis/workflow/v1alpha1/generated.proto + touch $@ # this target will also create a .pb.go and a .pb.gw.go file, but in Make 3 we cannot use _grouped target_, instead we must choose # on file to represent all of them @@ -937,3 +939,10 @@ devcontainer-build: $(TOOL_DEVCONTAINER) .PHONY: devcontainer-up devcontainer-up: $(TOOL_DEVCONTAINER) devcontainer up --workspace-folder . + +# gRPC/protobuf generation for artifact.proto +pkg/apiclient/artifact/artifact.swagger.json: $(PROTO_BINARIES) $(TYPES) pkg/apiclient/artifact/artifact.proto + $(call protoc,pkg/apiclient/artifact/artifact.proto) + +# Add artifact-proto to swagger dependencies +swagger: pkg/apiclient/artifact/artifact.swagger.json diff --git a/README.md b/README.md index b18615926ff6..2627bfedb3c7 100644 --- a/README.md +++ b/README.md @@ -87,7 +87,7 @@ Check out our [Java, Golang and Python clients](docs/client-libraries.md). An incomplete list of features Argo Workflows provide: * UI to visualize and manage Workflows -* Artifact support (S3, Artifactory, Alibaba Cloud OSS, Azure Blob Storage, HTTP, Git, GCS, raw) +* Artifact support (S3, Artifactory, Alibaba Cloud OSS, Azure Blob Storage, HTTP, Git, GCS, raw, plugins) * Workflow templating to store commonly used Workflows in the cluster * Archiving Workflows after executing for later access * Scheduled workflows using cron diff --git a/api/jsonschema/schema.json b/api/jsonschema/schema.json index e15a29914270..c2201b08cf5b 100644 --- a/api/jsonschema/schema.json +++ b/api/jsonschema/schema.json @@ -4078,6 +4078,10 @@ "description": "Path is the container path to the artifact", "type": "string" }, + "plugin": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.PluginArtifact", + "description": "Plugin contains plugin artifact location details" + }, "raw": { "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.RawArtifact", "description": "Raw contains raw artifact location details" @@ -4153,6 +4157,10 @@ "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.OSSArtifact", "description": "OSS contains OSS artifact location details" }, + "plugin": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.PluginArtifact", + "description": "Plugin contains plugin artifact location details" + }, "raw": { "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.RawArtifact", "description": "Raw contains raw artifact location details" @@ -4239,6 +4247,10 @@ "description": "Path is the container path to the artifact", "type": "string" }, + "plugin": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.PluginArtifact", + "description": "Plugin contains plugin artifact location details" + }, "raw": { "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.RawArtifact", "description": "Raw contains raw artifact location details" @@ -4288,6 +4300,10 @@ "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.OSSArtifactRepository", "description": "OSS stores artifact in a OSS-compliant object store" }, + "plugin": { + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.PluginArtifactRepository", + "description": "Plugin stores artifact in a plugin-specific artifact repository" + }, "s3": { "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.S3ArtifactRepository", "description": "S3 stores artifact in a S3-compliant object store" @@ -6364,6 +6380,52 @@ "description": "Plugin is an Object with exactly one key", "type": "object" }, + "io.argoproj.workflow.v1alpha1.PluginArtifact": { + "description": "PluginArtifact is the location of a plugin artifact", + "properties": { + "configuration": { + "description": "Configuration is the plugin defined configuration for the artifact driver plugin", + "type": "string" + }, + "connectionTimeoutSeconds": { + "description": "ConnectionTimeoutSeconds is the timeout for the artifact driver connection, 5 seconds if not set", + "type": "integer" + }, + "key": { + "description": "Key is the path in the artifact repository where the artifact resides", + "type": "string" + }, + "name": { + "description": "Name is the name of the artifact driver plugin", + "type": "string" + } + }, + "required": [ + "name", + "configuration", + "key" + ], + "type": "object" + }, + "io.argoproj.workflow.v1alpha1.PluginArtifactRepository": { + "description": "PluginArtifactRepository defines the controller configuration for a plugin artifact repository", + "properties": { + "configuration": { + "type": "string" + }, + "keyFormat": { + "type": "string" + }, + "name": { + "type": "string" + } + }, + "required": [ + "name", + "configuration" + ], + "type": "object" + }, "io.argoproj.workflow.v1alpha1.PodGC": { "description": "PodGC describes how to delete completed pods as they complete", "properties": { diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 3366d4cc8814..a0c518a512fc 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -8380,6 +8380,10 @@ "description": "Path is the container path to the artifact", "type": "string" }, + "plugin": { + "description": "Plugin contains plugin artifact location details", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.PluginArtifact" + }, "raw": { "description": "Raw contains raw artifact location details", "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.RawArtifact" @@ -8452,6 +8456,10 @@ "description": "OSS contains OSS artifact location details", "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.OSSArtifact" }, + "plugin": { + "description": "Plugin contains plugin artifact location details", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.PluginArtifact" + }, "raw": { "description": "Raw contains raw artifact location details", "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.RawArtifact" @@ -8541,6 +8549,10 @@ "description": "Path is the container path to the artifact", "type": "string" }, + "plugin": { + "description": "Plugin contains plugin artifact location details", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.PluginArtifact" + }, "raw": { "description": "Raw contains raw artifact location details", "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.RawArtifact" @@ -8587,6 +8599,10 @@ "description": "OSS stores artifact in a OSS-compliant object store", "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.OSSArtifactRepository" }, + "plugin": { + "description": "Plugin stores artifact in a plugin-specific artifact repository", + "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.PluginArtifactRepository" + }, "s3": { "description": "S3 stores artifact in a S3-compliant object store", "$ref": "#/definitions/io.argoproj.workflow.v1alpha1.S3ArtifactRepository" @@ -10644,6 +10660,52 @@ "description": "Plugin is an Object with exactly one key", "type": "object" }, + "io.argoproj.workflow.v1alpha1.PluginArtifact": { + "description": "PluginArtifact is the location of a plugin artifact", + "type": "object", + "required": [ + "name", + "configuration", + "key" + ], + "properties": { + "configuration": { + "description": "Configuration is the plugin defined configuration for the artifact driver plugin", + "type": "string" + }, + "connectionTimeoutSeconds": { + "description": "ConnectionTimeoutSeconds is the timeout for the artifact driver connection, 5 seconds if not set", + "type": "integer" + }, + "key": { + "description": "Key is the path in the artifact repository where the artifact resides", + "type": "string" + }, + "name": { + "description": "Name is the name of the artifact driver plugin", + "type": "string" + } + } + }, + "io.argoproj.workflow.v1alpha1.PluginArtifactRepository": { + "description": "PluginArtifactRepository defines the controller configuration for a plugin artifact repository", + "type": "object", + "required": [ + "name", + "configuration" + ], + "properties": { + "configuration": { + "type": "string" + }, + "keyFormat": { + "type": "string" + }, + "name": { + "type": "string" + } + } + }, "io.argoproj.workflow.v1alpha1.PodGC": { "description": "PodGC describes how to delete completed pods as they complete", "type": "object", diff --git a/cmd/argoexec/commands/artifact/delete.go b/cmd/argoexec/commands/artifact/delete.go index 5e63c516792f..52f94456a0ab 100644 --- a/cmd/argoexec/commands/artifact/delete.go +++ b/cmd/argoexec/commands/artifact/delete.go @@ -6,6 +6,7 @@ import ( "fmt" "os" "path/filepath" + "strings" "github.com/spf13/cobra" @@ -16,10 +17,13 @@ import ( "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" workflow "github.com/argoproj/argo-workflows/v3/pkg/client/clientset/versioned" wfv1alpha1 "github.com/argoproj/argo-workflows/v3/pkg/client/clientset/versioned/typed/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/util/logging" "github.com/argoproj/argo-workflows/v3/util/retry" waitutil "github.com/argoproj/argo-workflows/v3/util/wait" - executor "github.com/argoproj/argo-workflows/v3/workflow/artifacts" + "github.com/argoproj/argo-workflows/v3/workflow/artifacts" "github.com/argoproj/argo-workflows/v3/workflow/common" + "github.com/argoproj/argo-workflows/v3/workflow/executor" + "github.com/argoproj/argo-workflows/v3/workflow/executor/emissary" ) func NewArtifactDeleteCommand() *cobra.Command { @@ -28,6 +32,7 @@ func NewArtifactDeleteCommand() *cobra.Command { SilenceUsage: true, RunE: func(cmd *cobra.Command, args []string) error { ctx := cmd.Context() + logger := logging.RequireLoggerFromContext(ctx) namespace := client.Namespace(ctx) clientConfig := client.GetConfig() @@ -46,7 +51,25 @@ func NewArtifactDeleteCommand() *cobra.Command { if err != nil { return err } + logger.Info(ctx, "artifacts deleted") } + em, err := emissary.New() + if err != nil { + return err + } + pluginNamesEnv := os.Getenv(common.EnvVarArtifactPluginNames) + if pluginNamesEnv == "" { + logger.Info(ctx, "no artifact sidecars to kill") + return nil + } + artifactSidecars := strings.Split(pluginNamesEnv, ",") + logger.WithFields(logging.Fields{"artifactSidecars": artifactSidecars}).Info(ctx, "killing artifact sidecars") + err = em.Kill(ctx, artifactSidecars, executor.GetTerminationGracePeriodDuration()) + if err != nil { + logger.WithError(err).WithFields(logging.Fields{"artifactSidecars": artifactSidecars}).Error(ctx, "failed to kill artifact sidecars") + return err + } + logger.WithFields(logging.Fields{"artifactSidecars": artifactSidecars}).Info(ctx, "artifact sidecars killed") return nil }, } @@ -79,7 +102,7 @@ func deleteArtifacts(labelSelector string, ctx context.Context, artifactGCTaskIn } } - drv, err := executor.NewDriver(ctx, &artifact, resources) + drv, err := artifacts.NewDriver(ctx, &artifact, resources) if err != nil { return err } diff --git a/cmd/argoexec/commands/artifact_plugin_init.go b/cmd/argoexec/commands/artifact_plugin_init.go new file mode 100644 index 000000000000..da78fd321caf --- /dev/null +++ b/cmd/argoexec/commands/artifact_plugin_init.go @@ -0,0 +1,80 @@ +package commands + +import ( + "context" + "fmt" + "os" + "os/signal" + "syscall" + + "github.com/argoproj/pkg/stats" + "github.com/spf13/cobra" + + wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/util/logging" + "github.com/argoproj/argo-workflows/v3/workflow/executor/osspecific" +) + +func NewArtifactPluginInitCommand() *cobra.Command { + var artifactPlugin string + command := cobra.Command{ + Use: "artifact-plugin-init", + Short: "Load artifacts from an artifact plugin only, as an init container", + RunE: func(cmd *cobra.Command, args []string) error { + ctx := cmd.Context() + logger := logging.RequireLoggerFromContext(ctx) + + name, args := args[0], args[1:] + logger.WithFields(logging.Fields{"name": name, "args": args}).Debug(ctx, "starting command") + + go func() { + command, closer, err := startCommand(ctx, name, args, template) + if err != nil { + logger.WithError(err).Error(ctx, "failed to start command") + return + } + defer closer() + // setup signal handlers + signals := make(chan os.Signal, 1) + defer close(signals) + signal.Notify(signals) + defer signal.Reset() + + go func() { + for s := range signals { + if osspecific.CanIgnoreSignal(s) { + logger.WithField("signal", s).Debug(ctx, "ignore signal") + continue + } + + logger.WithField("signal", s).Debug(ctx, "forwarding signal") + _ = osspecific.Kill(command.Process.Pid, s.(syscall.Signal)) + } + }() + }() + err := loadArtifactPlugin(cmd.Context(), wfv1.ArtifactPluginName(artifactPlugin)) + if err != nil { + return fmt.Errorf("%+v", err) + } + return nil + }, + } + command.Flags().StringVar(&artifactPlugin, "plugin-name", "", "Artifact plugin name") + return &command +} + +func loadArtifactPlugin(ctx context.Context, pluginName wfv1.ArtifactPluginName) error { + if err := os.MkdirAll(pluginName.SocketDir(), 0755); err != nil { + return err + } + wfExecutor := initExecutor(ctx) + defer wfExecutor.HandleError(ctx) + defer stats.LogStats() + + err := wfExecutor.LoadArtifactsFromPlugin(ctx, wfv1.ArtifactPluginName(pluginName)) + if err != nil { + wfExecutor.AddError(ctx, err) + return err + } + return nil +} diff --git a/cmd/argoexec/commands/artifact_plugin_sidecar.go b/cmd/argoexec/commands/artifact_plugin_sidecar.go new file mode 100644 index 000000000000..1176b3e3d2a8 --- /dev/null +++ b/cmd/argoexec/commands/artifact_plugin_sidecar.go @@ -0,0 +1,110 @@ +package commands + +import ( + "os" + "os/signal" + "path/filepath" + "strconv" + "syscall" + "time" + + "github.com/spf13/cobra" + + "github.com/argoproj/argo-workflows/v3/util/errors" + "github.com/argoproj/argo-workflows/v3/util/logging" + "github.com/argoproj/argo-workflows/v3/workflow/executor/osspecific" +) + +func NewArtifactPluginSidecarCommand() *cobra.Command { + command := cobra.Command{ + Use: "artifact-plugin-sidecar", + Short: "Run an artifact plugin as a sidecar", + RunE: func(cmd *cobra.Command, args []string) error { + exitCode := 64 + ctx := cmd.Context() + logger := logging.RequireLoggerFromContext(ctx) + + osspecific.AllowGrantingAccessToEveryone() + + // Dir permission set to rwxrwxrwx, so that non-root containers can write exitcode and signal files. + if err := os.MkdirAll(varRunArgo+"/ctr/"+containerName, 0o777); err != nil { + return err + } + + name, args := args[0], args[1:] + logger.WithFields(logging.Fields{"name": name, "args": args}).Debug(ctx, "starting command") + + command, closer, err := startCommand(ctx, name, args, template) + if err != nil { + logger.WithError(err).Error(ctx, "failed to start command") + return err + } + defer closer() + // setup signal handlers + signals := make(chan os.Signal, 1) + defer close(signals) + signal.Notify(signals) + defer signal.Reset() + + defer func() { + err := os.WriteFile(varRunArgo+"/ctr/"+containerName+"/exitcode", []byte(strconv.Itoa(exitCode)), 0o644) + if err != nil { + logger.WithError(err).Error(ctx, "failed to write exit code") + } + }() + + go func() { + for s := range signals { + logger.WithField("signal", s).Debug(ctx, "ignore signal") + // Artifact sidecard ignore sigterm, and only honor that over th + // file based termination from the wait container so we hang + // around to service it even when kubernetes is SIGTERMing us + if osspecific.CanIgnoreSignal(s) || s == syscall.SIGTERM { + logger.WithField("signal", s).Debug(ctx, "ignore signal") + continue + } + + logger.WithField("signal", s).Debug(ctx, "forwarding signal") + _ = osspecific.Kill(command.Process.Pid, s.(syscall.Signal)) + } + }() + go func() { + signalPath := filepath.Clean(filepath.Join(varRunArgo, "ctr", containerName, "signal")) + logger.WithField("signalPath", signalPath).Info(ctx, "waiting for signals") + for { + select { + case <-ctx.Done(): + return + default: + data, _ := os.ReadFile(signalPath) + _ = os.Remove(signalPath) + s, _ := strconv.Atoi(string(data)) + logger.WithFields(logging.Fields{ + "signal": s, + "signalPath": signalPath, + }).Info(ctx, "received signal") + if s > 0 { + _ = osspecific.Kill(command.Process.Pid, syscall.Signal(s)) + } + time.Sleep(2 * time.Second) + } + } + }() + + cmdErr := osspecific.Wait(command.Process) + if cmdErr == nil { + exitCode = 0 + } else if exitError, ok := cmdErr.(errors.Exited); ok { + if exitError.ExitCode() >= 0 { + exitCode = exitError.ExitCode() + } else { + exitCode = 137 // SIGTERM + } + } + + logger.Info(ctx, "artifact plugin sidecar command exited") + return nil + }, + } + return &command +} diff --git a/cmd/argoexec/commands/emissary.go b/cmd/argoexec/commands/emissary.go index 91ffd27466de..a5519ce83081 100644 --- a/cmd/argoexec/commands/emissary.go +++ b/cmd/argoexec/commands/emissary.go @@ -161,14 +161,20 @@ func NewEmissaryCommand() *cobra.Command { ctx, cancel := context.WithCancel(ctx) defer cancel() go func() { + signalPath := filepath.Clean(filepath.Join(varRunArgo, "ctr", containerName, "signal")) + logger.WithField("signalPath", signalPath).Info(ctx, "waiting for signals") for { select { case <-ctx.Done(): return default: - data, _ := os.ReadFile(filepath.Clean(varRunArgo + "/ctr/" + containerName + "/signal")) - _ = os.Remove(varRunArgo + "/ctr/" + containerName + "/signal") + data, _ := os.ReadFile(signalPath) + _ = os.Remove(signalPath) s, _ := strconv.Atoi(string(data)) + logger.WithFields(logging.Fields{ + "signal": s, + "signalPath": signalPath, + }).Info(ctx, "received signal") if s > 0 { _ = osspecific.Kill(pid, syscall.Signal(s)) } diff --git a/cmd/argoexec/commands/init.go b/cmd/argoexec/commands/init.go index dc18feeea523..ba5622e1bb4b 100644 --- a/cmd/argoexec/commands/init.go +++ b/cmd/argoexec/commands/init.go @@ -38,7 +38,7 @@ func loadArtifacts(ctx context.Context) error { wfExecutor.AddError(ctx, err) return err } - err = wfExecutor.LoadArtifacts(ctx) + err = wfExecutor.LoadArtifactsWithoutPlugins(ctx) if err != nil { wfExecutor.AddError(ctx, err) return err diff --git a/cmd/argoexec/commands/root.go b/cmd/argoexec/commands/root.go index fc0471f4bf41..e40045295f61 100644 --- a/cmd/argoexec/commands/root.go +++ b/cmd/argoexec/commands/root.go @@ -73,6 +73,8 @@ func NewRootCommand() *cobra.Command { }, } command.AddCommand(NewAgentCommand()) + command.AddCommand(NewArtifactPluginInitCommand()) + command.AddCommand(NewArtifactPluginSidecarCommand()) command.AddCommand(NewEmissaryCommand()) command.AddCommand(NewInitCommand()) command.AddCommand(NewKillCommand()) diff --git a/cmd/argoexec/commands/wait.go b/cmd/argoexec/commands/wait.go index d41f65d1b130..f70dc4090bc2 100644 --- a/cmd/argoexec/commands/wait.go +++ b/cmd/argoexec/commands/wait.go @@ -3,12 +3,17 @@ package commands import ( "context" "fmt" + "os" + "strings" "time" "github.com/argoproj/pkg/stats" "github.com/spf13/cobra" "github.com/argoproj/argo-workflows/v3/util/logging" + "github.com/argoproj/argo-workflows/v3/workflow/common" + "github.com/argoproj/argo-workflows/v3/workflow/executor" + "github.com/argoproj/argo-workflows/v3/workflow/executor/emissary" ) func NewWaitCommand() *cobra.Command { @@ -79,11 +84,37 @@ func waitContainer(ctx context.Context) error { logArtifacts := wfExecutor.SaveLogs(bgCtx) artifacts = append(artifacts, logArtifacts...) - // Try to upsert TaskResult. If it fails, we will try to update the Pod's Annotations err = wfExecutor.ReportOutputs(bgCtx, artifacts) if err != nil { wfExecutor.AddError(ctx, err) } + err = killArtifactSidecars(bgCtx) + if err != nil { + wfExecutor.AddError(ctx, err) + } + return wfExecutor.HasError() } + +func killArtifactSidecars(ctx context.Context) error { + logger := logging.RequireLoggerFromContext(ctx) + em, err := emissary.New() + if err != nil { + return err + } + pluginNamesEnv := os.Getenv(common.EnvVarArtifactPluginNames) + if pluginNamesEnv == "" { + logger.Info(ctx, "no artifact sidecars to kill") + return nil + } + artifactSidecars := strings.Split(pluginNamesEnv, ",") + logger.WithFields(logging.Fields{"numSidecars": len(artifactSidecars), "artifactSidecars": artifactSidecars}).Info(ctx, "killing artifact sidecars") + err = em.Kill(ctx, artifactSidecars, executor.GetTerminationGracePeriodDuration()) + if err != nil { + logger.WithError(err).WithFields(logging.Fields{"artifactSidecars": artifactSidecars}).Error(ctx, "failed to kill artifact sidecars") + return err + } + logger.WithFields(logging.Fields{"artifactSidecars": artifactSidecars}).Info(ctx, "artifact sidecars killed") + return nil +} diff --git a/config/config.go b/config/config.go index 2812c8502282..1b821cb66666 100644 --- a/config/config.go +++ b/config/config.go @@ -118,6 +118,38 @@ type Config struct { // Synchronization via databases config Synchronization *SyncConfig `json:"synchronization,omitempty"` + + // ArtifactDrivers lists artifact driver plugins we can use + ArtifactDrivers []ArtifactDriver `json:"artifactDrivers,omitempty"` +} + +// ArtifactDriver is a plugin for an artifact driver +type ArtifactDriver struct { + // Name is the name of the artifact driver plugin + Name wfv1.ArtifactPluginName `json:"name"` + // Image is the docker image of the artifact driver + Image string `json:"image"` +} + +func (c Config) GetArtifactDriver(name wfv1.ArtifactPluginName) (ArtifactDriver, error) { + for _, driver := range c.ArtifactDrivers { + if driver.Name == name { + return driver, nil + } + } + return ArtifactDriver{}, fmt.Errorf("artifact driver %s not found", name) +} + +func (c Config) GetArtifactDrivers(plugins []wfv1.ArtifactPluginName) ([]ArtifactDriver, error) { + drivers := []ArtifactDriver{} + for _, plugin := range plugins { + driver, err := c.GetArtifactDriver(plugin) + if err != nil { + return nil, err + } + drivers = append(drivers, driver) + } + return drivers, nil } func (c Config) GetExecutor() *apiv1.Container { diff --git a/docs/README.md b/docs/README.md index b4c15eabf1c8..b6427bbe494f 100644 --- a/docs/README.md +++ b/docs/README.md @@ -87,7 +87,7 @@ You're here! An incomplete list of features Argo Workflows provide: * UI to visualize and manage Workflows -* Artifact support (S3, Artifactory, Alibaba Cloud OSS, Azure Blob Storage, HTTP, Git, GCS, raw) +* Artifact support (S3, Artifactory, Alibaba Cloud OSS, Azure Blob Storage, HTTP, Git, GCS, raw, plugins) * Workflow templating to store commonly used Workflows in the cluster * Archiving Workflows after executing for later access * Scheduled workflows using cron diff --git a/docs/artifact-plugin.md b/docs/artifact-plugin.md new file mode 100644 index 000000000000..0b34e2b5fa70 --- /dev/null +++ b/docs/artifact-plugin.md @@ -0,0 +1,314 @@ +# Artifact Driver/Plugin Development + +This document provides guidance for developers who want to create custom artifact drivers/plugins for Argo Workflows. + +## Overview + +Artifact drivers/plugins allow you to extend Argo Workflows with alternative storage solutions or artifact handling logic. +By implementing a plugin, you can integrate with proprietary storage systems, add custom processing logic, or support specialized artifact formats. + +## High-Level Requirements + +To create an artifact plugin, you need to: + +### 1. Implement a GRPC Server + +Your plugin's entrypoint must run a GRPC server that: + +- Listens on the Unix socket path provided as the first and only command-line parameter. The `unix://` prefix should not be necessary. +- Implements the artifact service interface +- Handles artifact operations (load, save, delete, etc.) +- Shuts down gracefully when given a SIGTERM signal + +The GRPC interface is defined in **[`artifact.proto`](https://github.com/argoproj/argo-workflows/blob/main/pkg/apiclient/artifact/artifact.proto)**. +This contains the main `ArtifactService` interface and all request/response message types your plugin must implement. + +The plugin can be implemented in any programming language that supports GRPC, including: + +- Go +- Python +- Java +- Rust +- Node.JS +- C# +- [and others](https://grpc.io/docs/languages/) + +Choose the language that best fits your team's expertise and your storage backend's SDK requirements. + +### 2. Create and Distribute a Docker Image + +Your plugin must be packaged as a Docker image that contains: + +- Your plugin implementation +- All necessary dependencies and runtime requirements +- The GRPC server that implements the artifact interface +- `/tmp` must exist and be writable by the container user in your image or the image won't work for loading artifacts + +The Docker image will be deployed alongside workflow pods as sidecars and init containers. +For ease of deployment make the image run as non-root by default, as the argo-server pod will run as non-root. + +## Implementation Steps + +Follow these steps to implement an artifact plugin in your chosen language: + +### 1. Download Protocol Definition + +Download the [`artifact.proto`](https://github.com/argoproj/argo-workflows/blob/main/pkg/apiclient/artifact/artifact.proto) file to your project. + +### 2. Generate GRPC Server Code + +Use your language's GRPC tooling to generate server stubs from the protocol definition. +You will need the `googleapis` protocol definitions from . + +#### Go + +```bash +# Install protoc-gen-go and protoc-gen-go-grpc +go install google.golang.org/protobuf/cmd/protoc-gen-go@latest +go install google.golang.org/grpc/cmd/protoc-gen-go-grpc@latest + +# Generate Go code +protoc --go_out=. --go-grpc_out=. artifact.proto +``` + +#### Python + +```bash +# Create a project and venv +python -m venv .venv && source .venv/bin/activate + +# Install grpcio-tools and protobuf +pip install grpcio-tools protobuf + +# Create a module +mkdir my_artifact_plugin + +# Generate Python code +python -m grpc_tools.protoc --python_out=artifact_plugin --pyi_out=artifact_plugin --grpc_python_out=artifact_plugin -I googleapis -I . artifact.proto +``` + +#### Java + +```bash +# Using protoc with Java plugin +protoc --java_out=src/main/java --grpc-java_out=src/main/java artifact.proto +``` + +#### Rust + +```rust +// Add to Cargo.toml +[build-dependencies] +tonic-build = "0.10" + +// In build.rs +fn main() { + tonic_build::compile_protos("artifact.proto").unwrap(); +} +``` + +#### Node.JS + +```bash +# Install grpc-tools +npm install grpc-tools + +# Generate JavaScript code +grpc_tools_node_protoc --js_out=import_style=commonjs:. --grpc_out=grpc_js:. artifact.proto +``` + +#### C\# + +```bash +# Install Grpc.Tools package, then use protoc +protoc --csharp_out=. --grpc_out=. --plugin=protoc-gen-grpc=grpc_csharp_plugin artifact.proto +``` + +### 3. Implement Required Methods + +Your GRPC server must implement these six methods from the `ArtifactService` interface: + +#### Required Methods + +1. **`Load(LoadArtifactRequest)` → `LoadArtifactResponse`** + - Downloads an artifact from your storage system to the specified local path + - Called during workflow execution to retrieve input artifacts + +2. **`Save(SaveArtifactRequest)` → `SaveArtifactResponse`** + - Uploads an artifact from a local path to your storage system + - Called to store output artifacts after step completion + +3. **`Delete(DeleteArtifactRequest)` → `DeleteArtifactResponse`** + - Removes an artifact from your storage system + - Used for artifact garbage collection + +4. **`ListObjects(ListObjectsRequest)` → `ListObjectsResponse`** + - Lists objects/files within an artifact location + - Used by the UI and CLI for artifact browsing + +5. **`IsDirectory(IsDirectoryRequest)` → `IsDirectoryResponse`** + - Determines if an artifact location represents a directory or file + - Used to handle directory artifacts appropriately + +6. **`OpenStream(OpenStreamRequest)` → `stream OpenStreamResponse`** + - Streams artifact content directly to clients + - Used for efficient artifact downloads in the UI + - Could be implemented as Load() and then streaming the data from the local file, which is what some built-in drivers do, but this is not recommended as it is not efficient. + +#### Implementation Notes + +- Parse the plugin configuration from `artifact.plugin.configuration` field in each request +- Use the `artifact.plugin.key` field to identify the specific artifact location in your storage +- Handle errors gracefully and return appropriate error messages +- Support both file and directory artifacts where applicable +- Consider implementing timeouts and retry logic for storage operations +- IMPORTANT: SIGTERM signals must be handled gracefully to exit with a `0` exit code + +### 4. Build and Package + +Package your plugin as a Docker image with your GRPC server as the entrypoint. +The server should accept a single command-line argument specifying the Unix socket path to listen on. + +### 5. Local Testing + +For faster development iteration, test your plugin locally using a simple GRPC client: + +#### Start Your Plugin Server + +Run your plugin binary directly, providing a Unix socket path: + +```bash +# Start your plugin server listening on a Unix socket +./your-plugin-binary /tmp/plugin.sock +``` + +or in a container, using the socket path as the command and exposing the socket path as a volume: + +```bash +docker run -v /tmp/plugin.sock:/tmp/plugin.sock your-plugin-image /tmp/plugin.sock +``` + +#### Possibly test with `grpcurl` + +Use [`grpcurl`](https://github.com/fullstorydev/grpcurl) for quick testing without writing client code. +Your server would need to be running and listening on the socket path for this to work. +Your server must also have [reflection enabled](https://grpc.io/docs/guides/reflection/), which is not the default. +Although `grpcurl` is written in Go, it can be used to test plugins written in any language. + +```bash +# Install grpcurl +go install github.com/fullstorydev/grpcurl/cmd/grpcurl@latest + +# Test Load method (requires reflection enabled in your server) +grpcurl -plaintext -unix /tmp/plugin.sock \ + -d '{ + "input_artifact": { + "name": "test-artifact", + "plugin": { + "name": "my-plugin", + "configuration": "{\"bucket\": \"test-bucket\"}", + "key": "test/file.txt" + } + } + }, + "path": "/tmp/test-download.txt" + }' \ + artifact.ArtifactService/Load +``` + +#### Create Test Clients + +Create simple GRPC clients to test each method: + +##### Go Test Client Example + +```go +package main + +import ( + "context" + "log" + "net" + "google.golang.org/grpc" + pb "path/to/your/generated/artifact" +) + +func main() { + // Connect to Unix socket + conn, err := grpc.Dial("unix:///tmp/plugin.sock", grpc.WithInsecure()) + if err != nil { + log.Fatal(err) + } + defer conn.Close() + + client := pb.NewArtifactServiceClient(conn) + + // Test Load method + loadReq := &pb.LoadArtifactRequest{ + InputArtifact: &pb.Artifact{ + Name: "test-artifact", + Plugin: &pb.PluginArtifact{ + Name: "my-plugin", + Configuration: `{"bucket": "test-bucket", "endpoint": "localhost:9000"}`, + Key: "test/file.txt", + }, + }, + Path: "/tmp/downloaded-file.txt", + } + + loadResp, err := client.Load(context.Background(), loadReq) + if err != nil { + log.Printf("Load failed: %v", err) + } else { + log.Printf("Load success: %v", loadResp.Success) + } + + // Test other methods similarly... +} +``` + +##### Python Test Client Example + +```python +import grpc +import artifact_pb2 +import artifact_pb2_grpc + +def test_plugin(): + # Connect to Unix socket + channel = grpc.insecure_channel('unix:///tmp/plugin.sock') + stub = artifact_pb2_grpc.ArtifactServiceStub(channel) + + # Test Load method + artifact = artifact_pb2.Artifact( + name="test-artifact", + plugin=artifact_pb2.PluginArtifact( + name="my-plugin", + configuration='{"bucket": "test-bucket", "endpoint": "localhost:9000"}', + key="test/file.txt" + ) + ) + + request = artifact_pb2.LoadArtifactRequest( + input_artifact=artifact, + path="/tmp/downloaded-file.txt" + ) + + try: + response = stub.Load(request) + print(f"Load success: {response.success}") + except grpc.RpcError as e: + print(f"Load failed: {e}") + +if __name__ == "__main__": + test_plugin() +``` + +### 6. Integration Testing and Deployment + +Once local testing passes, test with the full workflow controller: + +1. Build and push your Docker image +2. Configure it in the workflow controller ConfigMap, as shown under [Configuring Your Artifact Repository](configure-artifact-repository.md#plugin-configuration) +3. Create workflows that use your plugin for artifacts +4. Verify all artifact operations work correctly by using artifacts as inputs, outputs and performing garbage collection diff --git a/docs/configure-artifact-repository.md b/docs/configure-artifact-repository.md index 44ef704a3a41..32060ced2473 100644 --- a/docs/configure-artifact-repository.md +++ b/docs/configure-artifact-repository.md @@ -5,17 +5,18 @@ repository. Argo supports any S3 compatible artifact repository such as AWS, GCS and MinIO. This section shows how to configure the artifact repository. Subsequent sections will show how to use it. -| Name | Inputs | Outputs | Garbage Collection | Usage (Feb 2020) | -|---|---|---|---|---| -| Artifactory | Yes | Yes | No | 11% | -| Azure Blob | Yes | Yes | Yes | - | -| GCS | Yes | Yes | Yes | - | -| Git | Yes | No | No | - | -| HDFS | Yes | Yes | No | 3% | -| HTTP | Yes | Yes | No | 2% | -| OSS | Yes | Yes | No | - | -| Raw | Yes | No | No | 5% | -| S3 | Yes | Yes | Yes | 86% | +| Name | Inputs | Outputs | Garbage Collection | +|---|---|---|---| +| Artifactory | Yes | Yes | No | +| Azure Blob | Yes | Yes | Yes | +| GCS | Yes | Yes | Yes | +| Git | Yes | No | No | +| HDFS | Yes | Yes | No | +| HTTP | Yes | Yes | No | +| OSS | Yes | Yes | No | +| Plugin | Yes | Yes | Possible | +| Raw | Yes | No | No | +| S3 | Yes | Yes | Yes | The actual repository used by a workflow is chosen by the following rules: @@ -461,7 +462,7 @@ metadata: namespace: rrsa-demo annotations: pod-identity.alibabacloud.com/role-name: $your_ram_role_name - + --- apiVersion: v1 kind: ConfigMap @@ -509,7 +510,7 @@ artifacts: # workflow (for example, https://docs.microsoft.com/en-us/azure/aks/use-managed-identity) # then useSDKCreds should be set to true. The accountKeySecret is not required # and will not be used in this case. - useSDKCreds: true + useSDKCreds: true ``` ### Using Azure Access Keys @@ -552,7 +553,7 @@ You can also use an [Access Key](https://learn.microsoft.com/en-us/azure/storage # containing the base64 encoded credentials to the storage account. accountKeySecret: name: my-azure-storage-credentials - key: account-access-key + key: account-access-key ``` ### Using Azure Shared Access Signatures (SAS) @@ -762,11 +763,171 @@ configuring the default artifact repository described previously. args: ["cp -r /my-input-artifact /my-output-artifact"] ``` +## Using Artifact Plugins + +> v4.0 and after + +Argo Workflows supports extensible artifact drivers through a plugin system. +Artifact plugins allow you to integrate with alternative storage solutions or implement specialized artifact handling logic. + +### What are Artifact Plugins? + +Artifact plugins are containerized extensions that implement the artifact driver interface via GRPC. +They run as sidecars and init containers alongside your workflow pods to handle artifact operations. +Each plugin is distributed as a Docker image that contains all necessary dependencies. + +### Plugin Configuration + +To use artifact plugins, you must configure them in three places: + +1. **System Configuration**: Register available plugins in the workflow controller ConfigMap. +1. **Argo Server Configuration**: Add available plugins as sidecars in the argo-server Deployment. +1. **Workflow Usage**: Reference plugins in your workflow artifact definitions + +#### System Configuration + +Plugins must be registered in the workflow controller ConfigMap under the [`artifactDrivers`](workflow-controller-configmap.md#artifactdriver) section. +This allows the system administrator to control which plugins are available and their versions. + +See the [Workflow Controller ConfigMap documentation](workflow-controller-configmap.md#artifactdriver) for detailed configuration of the `artifactDrivers` field. + +Example workflow controller ConfigMap configuration: + +```yaml +apiVersion: v1 +kind: ConfigMap +metadata: + name: workflow-controller-configmap +data: + artifactDrivers: | + - name: my-custom-plugin + image: quay.io/myorg/my-artifact-plugin:v1.0.0 + - name: another-plugin + image: docker.io/myorg/another-plugin:v2.1.0 +``` + +#### Argo Server Configuration + +Plugins must be added as sidecars in the argo-server Deployment. +Each plugin sidecar communicates with the argo-server container via a Unix socket on a shared volume. + +The plugin sidecar receives the socket path as its first and only command-line argument. +Both the plugin sidecar and the main argo-server container must mount a shared volume at the same location to enable socket communication. +The socket must be located at `/tmp/artifact-plugins/{plugin-name}/socket` where `{plugin-name}` matches the plugin name configured in the workflow controller ConfigMap. + +Example configuration for adding two plugin sidecars to argo-server: + +```yaml +apiVersion: apps/v1 +kind: Deployment +metadata: + name: argo-server +spec: + template: + spec: + containers: + - name: argo-server + image: quay.io/argoproj/argocli:latest + volumeMounts: + - name: my-custom-plugin + mountPath: /tmp/artifact-plugins/my-custom-plugin + - name: another-plugin + mountPath: /tmp/artifact-plugins/another-plugin + - name: my-custom-plugin-artifact-driver + image: quay.io/myorg/my-artifact-plugin:v1.0.0 + args: + - /tmp/artifact-plugins/my-custom-plugin/socket + volumeMounts: + - name: my-custom-plugin + mountPath: /tmp/artifact-plugins/my-custom-plugin + - name: another-plugin-artifact-driver + image: docker.io/myorg/another-plugin:v2.1.0 + args: + - /tmp/artifact-plugins/another-plugin/socket + volumeMounts: + - name: another-plugin + mountPath: /tmp/artifact-plugins/another-plugin + volumes: + - name: my-custom-plugin + emptyDir: {} + - name: another-plugin + emptyDir: {} +``` + +Key requirements for the configuration: + +- Each plugin requires its own dedicated volume and mount path at `/tmp/artifact-plugins/{plugin-name}`. +- The socket path must be `/tmp/artifact-plugins/{plugin-name}/socket` where `{plugin-name}` exactly matches the `name` field in the workflow controller's `artifactDrivers` configuration. +- Both the argo-server container and the plugin sidecar must mount the same volume at the same path. +- The socket file name must be `socket` (not arbitrary) to match what the code expects. +- Use `emptyDir` volumes as they provide efficient shared storage for Unix sockets. + +#### Workflow Usage + +Once registered, you can use plugins in your workflows by specifying the `plugin` field in artifact definitions: + +```yaml +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +spec: + templates: + - name: plugin-example + inputs: + artifacts: + - name: my-input + path: /tmp/input + plugin: + name: my-custom-plugin + configuration: | + endpoint: https://my-storage.example.com + bucket: my-bucket + credentials: + username: myuser + password: mypass + key: path/to/my-artifact + outputs: + artifacts: + - name: my-output + path: /tmp/output + plugin: + name: my-custom-plugin + configuration: | + endpoint: https://my-storage.example.com + bucket: my-bucket + credentials: + username: myuser + password: mypass + key: path/to/output-artifact +``` + +### Plugin Parameters + +The `plugin` artifact type supports the following parameters: + +| Parameter | Type | Required | Description | +|-----------|------|----------|-------------| +| `name` | `string` | Yes | The name of the plugin as configured in `artifactDrivers` | +| `configuration` | `string` | Yes | Plugin-specific configuration passed to the plugin as-is | +| `key` | `string` | Yes | The path/key where the artifact is stored in the plugin's storage system, how this is used is plugin specific | +| `connectionTimeoutSeconds` | `int32` | No | Timeout for GRPC client connection once image has started (default: 5 seconds) | + +#### Configuration Format + +The `configuration` field is a free-form string that gets passed directly to the plugin. +While plugins can use any format, YAML is strongly recommended for consistency and readability. +Each plugin defines its own configuration schema - consult the plugin's documentation for specific requirements. + +### Available Plugins + +Plugins are developed and maintained separately from Argo Workflows core. +Check the plugin's documentation for instructions, configuration options, and usage examples. + +For developers wanting to create their own artifact plugins, see the [Artifact Plugin Development Guide](artifact-plugin.md). + ## Artifact Streaming -With artifact streaming, artifacts don’t need to be saved to disk first. Artifact streaming is only supported in the following -artifact drivers: S3 (v3.4+), Azure Blob (v3.4+), HTTP (v3.5+), Artifactory (v3.5+), and OSS (v3.6+). +With artifact streaming, artifacts don't need to be saved to disk first. Artifact streaming is only supported in the following +artifact drivers: S3 (v3.4+), Azure Blob (v3.4+), HTTP (v3.5+), Artifactory (v3.5+), OSS (v3.6+), and Plugin (v4.0+). -Previously, when a user would click the button to download an artifact in the UI, the artifact would need to be written to the -Argo Server’s disk first before downloading. If many users tried to download simultaneously, they would take up -disk space and fail the download. +Without artifact streaming, when a user would click the button to download an artifact in the UI, the artifact would need to be written to the Argo Server's disk first before downloading. +If many users tried to download simultaneously, they would take up disk space and fail the download. diff --git a/docs/executor_swagger.md b/docs/executor_swagger.md index 47415e172fe2..f0616857d0a2 100644 --- a/docs/executor_swagger.md +++ b/docs/executor_swagger.md @@ -234,6 +234,7 @@ It will marshall back to string - marshalling is not symmetric. | optional | boolean| `bool` | | | Make Artifacts optional, if Artifacts doesn't generate or exist | | | oss | [OSSArtifact](#o-s-s-artifact)| `OSSArtifact` | | | | | | path | string| `string` | | | Path is the container path to the artifact | | +| plugin | [PluginArtifact](#plugin-artifact)| `PluginArtifact` | | | | | | raw | [RawArtifact](#raw-artifact)| `RawArtifact` | | | | | | recurseMode | boolean| `bool` | | | If mode is set, apply the permission recursively into the artifact if it is a folder | | | s3 | [S3Artifact](#s3-artifact)| `S3Artifact` | | | | | @@ -296,6 +297,7 @@ of a single workflow step, which the executor will use as a default location to | hdfs | [HDFSArtifact](#h-d-f-s-artifact)| `HDFSArtifact` | | | | | | http | [HTTPArtifact](#http-artifact)| `HTTPArtifact` | | | | | | oss | [OSSArtifact](#o-s-s-artifact)| `OSSArtifact` | | | | | +| plugin | [PluginArtifact](#plugin-artifact)| `PluginArtifact` | | | | | | raw | [RawArtifact](#raw-artifact)| `RawArtifact` | | | | | | s3 | [S3Artifact](#s3-artifact)| `S3Artifact` | | | | | @@ -333,6 +335,7 @@ of a single workflow step, which the executor will use as a default location to | optional | boolean| `bool` | | | Make Artifacts optional, if Artifacts doesn't generate or exist | | | oss | [OSSArtifact](#o-s-s-artifact)| `OSSArtifact` | | | | | | path | string| `string` | | | Path is the container path to the artifact | | +| plugin | [PluginArtifact](#plugin-artifact)| `PluginArtifact` | | | | | | raw | [RawArtifact](#raw-artifact)| `RawArtifact` | | | | | | recurseMode | boolean| `bool` | | | If mode is set, apply the permission recursively into the artifact if it is a folder | | | s3 | [S3Artifact](#s3-artifact)| `S3Artifact` | | | | | @@ -340,6 +343,20 @@ of a single workflow step, which the executor will use as a default location to +### ArtifactPluginName + + +> ArtifactPluginName is the name of an artifact plugin + + + + +| Name | Type | Go type | Default | Description | Example | +|------|------|---------| ------- |-------------|---------| +| ArtifactPluginName | string| string | | ArtifactPluginName is the name of an artifact plugin | | + + + ### ArtifactoryArtifact @@ -2685,6 +2702,27 @@ type of volume that is owned by someone else (the system). `interface{}` +### PluginArtifact + + +> PluginArtifact is the location of a plugin artifact + + + + + + +**Properties** + +| Name | Type | Go type | Required | Default | Description | Example | +|------|------|---------|:--------:| ------- |-------------|---------| +| configuration | string| `string` | | | Configuration is the plugin defined configuration for the artifact driver plugin | | +| connectionTimeoutSeconds | int32 (formatted integer)| `int32` | | | ConnectionTimeoutSeconds is the timeout for the artifact driver connection, 5 seconds if not set | | +| key | string| `string` | | | Key is the path in the artifact repository where the artifact resides | | +| name | [ArtifactPluginName](#artifact-plugin-name)| `ArtifactPluginName` | | | | | + + + ### PodAffinity diff --git a/docs/fields.md b/docs/fields.md index 29a4a54e2313..bf0d0dcdd684 100644 --- a/docs/fields.md +++ b/docs/fields.md @@ -19,6 +19,8 @@ Workflow is the definition of a workflow resource - [`artifact-gc-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-gc-workflow.yaml) +- [`artifact-passing-explicit-plugin.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-explicit-plugin.yaml) + - [`artifact-passing-subpath.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-subpath.yaml) - [`artifact-passing.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing.yaml) @@ -502,6 +504,8 @@ WorkflowSpec is the specification of a Workflow. - [`artifact-gc-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-gc-workflow.yaml) +- [`artifact-passing-explicit-plugin.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-explicit-plugin.yaml) + - [`artifact-passing-subpath.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-subpath.yaml) - [`artifact-passing.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing.yaml) @@ -970,6 +974,8 @@ CronWorkflowSpec is the specification of a CronWorkflow - [`artifact-gc-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-gc-workflow.yaml) +- [`artifact-passing-explicit-plugin.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-explicit-plugin.yaml) + - [`artifact-passing-subpath.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-subpath.yaml) - [`artifact-passing.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing.yaml) @@ -1423,6 +1429,8 @@ Arguments to a template - [`artifact-disable-archive.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-disable-archive.yaml) +- [`artifact-passing-explicit-plugin.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-explicit-plugin.yaml) + - [`artifact-passing-subpath.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-subpath.yaml) - [`artifact-passing.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing.yaml) @@ -2037,6 +2045,8 @@ Outputs hold parameters, artifacts, and results from a step - [`artifact-gc-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-gc-workflow.yaml) +- [`artifact-passing-explicit-plugin.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-explicit-plugin.yaml) + - [`artifact-passing-subpath.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-subpath.yaml) - [`artifact-passing.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing.yaml) @@ -2216,6 +2226,8 @@ Artifact indicates an artifact to place at a specified path - [`artifact-gc-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-gc-workflow.yaml) +- [`artifact-passing-explicit-plugin.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-explicit-plugin.yaml) + - [`artifact-passing-subpath.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-subpath.yaml) - [`artifact-passing.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing.yaml) @@ -2306,6 +2318,7 @@ Artifact indicates an artifact to place at a specified path |`optional`|`boolean`|Make Artifacts optional, if Artifacts doesn't generate or exist| |`oss`|[`OSSArtifact`](#ossartifact)|OSS contains OSS artifact location details| |`path`|`string`|Path is the container path to the artifact| +|`plugin`|[`PluginArtifact`](#pluginartifact)|Plugin contains plugin artifact location details| |`raw`|[`RawArtifact`](#rawartifact)|Raw contains raw artifact location details| |`recurseMode`|`boolean`|If mode is set, apply the permission recursively into the artifact if it is a folder| |`s3`|[`S3Artifact`](#s3artifact)|S3 contains S3 artifact location details| @@ -2666,6 +2679,7 @@ ArtifactLocation describes a location for a single or multiple artifacts. It is |`hdfs`|[`HDFSArtifact`](#hdfsartifact)|HDFS contains HDFS artifact location details| |`http`|[`HTTPArtifact`](#httpartifact)|HTTP contains HTTP artifact location details| |`oss`|[`OSSArtifact`](#ossartifact)|OSS contains OSS artifact location details| +|`plugin`|[`PluginArtifact`](#pluginartifact)|Plugin contains plugin artifact location details| |`raw`|[`RawArtifact`](#rawartifact)|Raw contains raw artifact location details| |`s3`|[`S3Artifact`](#s3artifact)|S3 contains S3 artifact location details| @@ -2909,6 +2923,8 @@ Inputs are the mechanism for passing parameters, artifacts, volumes from one tem - [`artifact-disable-archive.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-disable-archive.yaml) +- [`artifact-passing-explicit-plugin.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-explicit-plugin.yaml) + - [`artifact-passing-subpath.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-subpath.yaml) - [`artifact-passing.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing.yaml) @@ -3111,6 +3127,12 @@ Memoization enables caching for the Outputs of the template Plugin is an Object with exactly one key +
+Examples with this field (click to open) + +- [`artifact-passing-explicit-plugin.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-explicit-plugin.yaml) +
+ ## ResourceTemplate ResourceTemplate is a template subtype to manipulate kubernetes resources @@ -3251,6 +3273,8 @@ WorkflowStep is a reference to a template to execute in a series of step - [`artifact-disable-archive.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-disable-archive.yaml) +- [`artifact-passing-explicit-plugin.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-explicit-plugin.yaml) + - [`artifact-passing-subpath.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-subpath.yaml) - [`artifact-passing.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing.yaml) @@ -3497,6 +3521,7 @@ ArtifactRepository represents an artifact repository in which a controller will |`gcs`|[`GCSArtifactRepository`](#gcsartifactrepository)|GCS stores artifact in a GCS object store| |`hdfs`|[`HDFSArtifactRepository`](#hdfsartifactrepository)|HDFS stores artifacts in HDFS| |`oss`|[`OSSArtifactRepository`](#ossartifactrepository)|OSS stores artifact in a OSS-compliant object store| +|`plugin`|[`PluginArtifactRepository`](#pluginartifactrepository)|Plugin stores artifact in a plugin-specific artifact repository| |`s3`|[`S3ArtifactRepository`](#s3artifactrepository)|S3 stores artifact in a S3-compliant object store| ## MemoizationStatus @@ -3799,6 +3824,24 @@ OSSArtifact is the location of an Alibaba Cloud OSS artifact |`securityToken`|`string`|SecurityToken is the user's temporary security token. For more details, check out: https://www.alibabacloud.com/help/doc-detail/100624.htm| |`useSDKCreds`|`boolean`|UseSDKCreds tells the driver to figure out credentials based on sdk defaults.| +## PluginArtifact + +PluginArtifact is the location of a plugin artifact + +
+Examples with this field (click to open) + +- [`artifact-passing-explicit-plugin.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-explicit-plugin.yaml) +
+ +### Fields +| Field Name | Field Type | Description | +|:----------:|:----------:|---------------| +|`configuration`|`string`|Configuration is the plugin defined configuration for the artifact driver plugin| +|`connectionTimeoutSeconds`|`integer`|ConnectionTimeoutSeconds is the timeout for the artifact driver connection, 5 seconds if not set| +|`key`|`string`|Key is the path in the artifact repository where the artifact resides| +|`name`|`string`|Name is the name of the artifact driver plugin| + ## RawArtifact RawArtifact allows raw string content to be placed as an artifact in a container @@ -4574,6 +4617,23 @@ OSSArtifactRepository defines the controller configuration for an OSS artifact r |`securityToken`|`string`|SecurityToken is the user's temporary security token. For more details, check out: https://www.alibabacloud.com/help/doc-detail/100624.htm| |`useSDKCreds`|`boolean`|UseSDKCreds tells the driver to figure out credentials based on sdk defaults.| +## PluginArtifactRepository + +PluginArtifactRepository defines the controller configuration for a plugin artifact repository + +
+Examples with this field (click to open) + +- [`artifact-passing-explicit-plugin.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-explicit-plugin.yaml) +
+ +### Fields +| Field Name | Field Type | Description | +|:----------:|:----------:|---------------| +|`configuration`|`string`|_No description available_| +|`keyFormat`|`string`|_No description available_| +|`name`|`string`|_No description available_| + ## S3ArtifactRepository S3ArtifactRepository defines the controller configuration for an S3 artifact repository @@ -4772,6 +4832,7 @@ ArtifactPaths expands a step from a collection of artifacts |`optional`|`boolean`|Make Artifacts optional, if Artifacts doesn't generate or exist| |`oss`|[`OSSArtifact`](#ossartifact)|OSS contains OSS artifact location details| |`path`|`string`|Path is the container path to the artifact| +|`plugin`|[`PluginArtifact`](#pluginartifact)|Plugin contains plugin artifact location details| |`raw`|[`RawArtifact`](#rawartifact)|Raw contains raw artifact location details| |`recurseMode`|`boolean`|If mode is set, apply the permission recursively into the artifact if it is a folder| |`s3`|[`S3Artifact`](#s3artifact)|S3 contains S3 artifact location details| @@ -4915,6 +4976,8 @@ ObjectMeta is metadata that all persisted resources must have, which includes al - [`artifact-gc-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-gc-workflow.yaml) +- [`artifact-passing-explicit-plugin.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-explicit-plugin.yaml) + - [`artifact-passing-subpath.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-subpath.yaml) - [`artifact-passing.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing.yaml) @@ -5596,6 +5659,8 @@ A single application container that you want to run within a pod. - [`artifact-gc-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-gc-workflow.yaml) +- [`artifact-passing-explicit-plugin.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-explicit-plugin.yaml) + - [`artifact-passing-subpath.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-subpath.yaml) - [`artifact-passing.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing.yaml) @@ -6565,6 +6630,8 @@ ImageVolumeSource represents a image volume resource. - [`artifact-gc-workflow.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-gc-workflow.yaml) +- [`artifact-passing-explicit-plugin.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-explicit-plugin.yaml) + - [`artifact-passing-subpath.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing-subpath.yaml) - [`artifact-passing.yaml`](https://github.com/argoproj/argo-workflows/blob/main/examples/artifact-passing.yaml) diff --git a/docs/plugins.md b/docs/plugins.md index fddbaecab886..1f69f62917ff 100644 --- a/docs/plugins.md +++ b/docs/plugins.md @@ -14,3 +14,9 @@ Each running workflow uses only one Agent pod, which can improve performance whe The same Agent pod also runs any [HTTP templates](http-template.md) that are part of the Workflow, offering additional performance advantages. You define [Executor plugin configuration](executor_plugins.md) as an `ExecutorPlugin` CustomResource. Both users and admins can write and install them. + +## Other Plugin Types + +In addition to Executor Plugins, Argo Workflows also supports: + +- **[Artifact Plugins](artifact-plugin.md)**: Extend artifact storage capabilities with custom storage drivers diff --git a/docs/workflow-controller-configmap.md b/docs/workflow-controller-configmap.md index 8c1df34796fd..9748639c185d 100644 --- a/docs/workflow-controller-configmap.md +++ b/docs/workflow-controller-configmap.md @@ -96,6 +96,7 @@ Config contains the root of the configuration settings for the workflow controll | `NavColor` | `string` | NavColor is an ui navigation bar background color | | `SSO` | [`SSOConfig`](#ssoconfig) | SSO in settings for single-sign on | | `Synchronization` | [`SyncConfig`](#syncconfig) | Synchronization via databases config | +| `ArtifactDrivers` | `Array<`[`ArtifactDriver`](#artifactdriver)`>` | ArtifactDrivers lists artifact driver plugins we can use | ## NodeEvents @@ -329,3 +330,14 @@ SyncConfig contains synchronization configuration for database locks (semaphores | `HeartbeatSeconds` | `int` | HeartbeatSeconds specifies how often to update controller heartbeat, if not set, the default value is 60 seconds | | `InactiveControllerSeconds` | `int` | InactiveControllerSeconds specifies when to consider a controller dead, if not set, the default value is 300 seconds | | `SemaphoreLimitCacheSeconds` | `int64` | SemaphoreLimitCacheSeconds specifies the duration in seconds before the workflow controller will re-fetch the limit for a semaphore from its associated data source. Defaults to 0 seconds (re-fetch every time the semaphore is checked). | + +## ArtifactDriver + +ArtifactDriver is a plugin for an artifact driver + +### Fields + +| Field Name | Field Type | Description | +|------------|-----------------------------------------------------------------|--------------------------------------------------| +| `Name` | `wfv1.ArtifactPluginName` (string (name of an artifact plugin)) | Name is the name of the artifact driver plugin | +| `Image` | `string` | Image is the docker image of the artifact driver | diff --git a/examples/artifact-passing-explicit-plugin.yaml b/examples/artifact-passing-explicit-plugin.yaml new file mode 100644 index 000000000000..d98058bf20df --- /dev/null +++ b/examples/artifact-passing-explicit-plugin.yaml @@ -0,0 +1,52 @@ +# This example demonstrates the ability to pass artifacts +# from one step to the next with an explicit artifact plugin +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: artifact-passing- +spec: + entrypoint: artifact-example + templates: + - name: artifact-example + steps: + - - name: generate-artifact + template: hello-world-to-file + - - name: consume-artifact + template: print-message-from-file + arguments: + artifacts: + - name: message + from: "{{steps.generate-artifact.outputs.artifacts.hello-art}}" + + - name: hello-world-to-file + container: + image: busybox + command: [sh, -c] + args: ["sleep 1; echo hello world | tee /tmp/hello_world.txt"] + outputs: + artifacts: + - name: hello-art + path: /tmp/hello_world.txt + plugin: + name: test + configuration: | + bucket: my-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: hi + + - name: print-message-from-file + inputs: + artifacts: + - name: message + path: /tmp/message + container: + image: alpine:latest + command: [sh, -c] + args: ["cat /tmp/message"] diff --git a/hack/docs/configdoc.go b/hack/docs/configdoc.go index cd3659d59231..4e8b67b85a47 100644 --- a/hack/docs/configdoc.go +++ b/hack/docs/configdoc.go @@ -437,6 +437,12 @@ func normalizeComment(comment string) string { // getInlineTypeDoc returns inline documentation for type aliases from AST func getInlineTypeDoc(typeName string) string { + // Handle specific type aliases that need to be documented inline as they are not in the openapi-gen generated swagger.json + switch typeName { + case "ArtifactPluginName", "wfv1.ArtifactPluginName": + return "string (name of an artifact plugin)" + } + ts, exists := typeSpecs[typeName] if !exists { return "" diff --git a/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml b/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml index 12c97a024392..a533a8c79cbe 100644 --- a/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml +++ b/manifests/base/crds/full/argoproj.io_clusterworkflowtemplates.yaml @@ -1801,6 +1801,32 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if not + set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -3092,6 +3118,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -5902,6 +5955,30 @@ spec: required: - key type: object + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout for + the artifact driver connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -9995,6 +10072,34 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the plugin + defined configuration for the artifact + driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact driver + connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -11308,6 +11413,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration is the + plugin defined configuration for + the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in + the artifact repository where + the artifact resides + type: string + name: + description: Name is the name of + the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -12639,6 +12774,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -15270,6 +15432,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -16591,6 +16780,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -17810,6 +18026,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -22133,6 +22376,34 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the plugin + defined configuration for the artifact + driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is + the timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -23405,6 +23676,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the + plugin defined configuration for + the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in the + artifact repository where the artifact + resides + type: string + name: + description: Name is the name of the + artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -27550,6 +27851,32 @@ spec: required: - key type: object + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if not + set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -31652,6 +31979,35 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the plugin + defined configuration for the artifact + driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact driver + connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the + artifact repository where the artifact + resides + type: string + name: + description: Name is the name of the + artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -32990,6 +33346,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration is + the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in + the artifact repository where + the artifact resides + type: string + name: + description: Name is the name + of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -34334,6 +34720,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -36976,6 +37389,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -38306,6 +38746,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -39536,6 +40003,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -43869,6 +44363,34 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the plugin + defined configuration for the artifact + driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact driver + connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -45172,6 +45694,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration is the + plugin defined configuration for + the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in + the artifact repository where + the artifact resides + type: string + name: + description: Name is the name of + the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details diff --git a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml index 7ef5605eea9d..16658a4bf28e 100644 --- a/manifests/base/crds/full/argoproj.io_cronworkflows.yaml +++ b/manifests/base/crds/full/argoproj.io_cronworkflows.yaml @@ -1901,6 +1901,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -3226,6 +3253,33 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -6067,6 +6121,33 @@ spec: required: - key type: object + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -10198,6 +10279,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the + plugin defined configuration for + the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in the + artifact repository where the artifact + resides + type: string + name: + description: Name is the name of the + artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -11558,6 +11669,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration is + the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path + in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name + of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -12930,6 +13071,33 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -15593,6 +15761,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -16937,6 +17132,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -18192,6 +18414,33 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -22545,6 +22794,35 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the plugin + defined configuration for the artifact + driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact driver + connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the + artifact repository where the artifact + resides + type: string + name: + description: Name is the name of the + artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -23873,6 +24151,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration is + the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in + the artifact repository where + the artifact resides + type: string + name: + description: Name is the name + of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -28059,6 +28367,33 @@ spec: required: - key type: object + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -32230,6 +32565,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration is the + plugin defined configuration for + the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in + the artifact repository where + the artifact resides + type: string + name: + description: Name is the name of + the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -33627,6 +33992,37 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration + is the plugin defined configuration + for the artifact driver + plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path + in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name + of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -35030,6 +35426,34 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the plugin + defined configuration for the artifact + driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is + the timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -37718,6 +38142,33 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -39090,6 +39541,33 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -40369,6 +40847,34 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the plugin + defined configuration for the artifact + driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is + the timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -44748,6 +45254,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the + plugin defined configuration for + the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in the + artifact repository where the artifact + resides + type: string + name: + description: Name is the name of the + artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -46098,6 +46634,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration is + the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path + in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name + of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details diff --git a/manifests/base/crds/full/argoproj.io_workflowartifactgctasks.yaml b/manifests/base/crds/full/argoproj.io_workflowartifactgctasks.yaml index 11b7fd58ffc3..27cb36b4a54e 100644 --- a/manifests/base/crds/full/argoproj.io_workflowartifactgctasks.yaml +++ b/manifests/base/crds/full/argoproj.io_workflowartifactgctasks.yaml @@ -781,6 +781,32 @@ spec: required: - key type: object + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if not + set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -1816,6 +1842,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: diff --git a/manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml b/manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml index 0cb7e0748c0f..668c565994c8 100644 --- a/manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml +++ b/manifests/base/crds/full/argoproj.io_workfloweventbindings.yaml @@ -897,6 +897,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: diff --git a/manifests/base/crds/full/argoproj.io_workflows.yaml b/manifests/base/crds/full/argoproj.io_workflows.yaml index 8e43a591421a..9670afbf4489 100644 --- a/manifests/base/crds/full/argoproj.io_workflows.yaml +++ b/manifests/base/crds/full/argoproj.io_workflows.yaml @@ -1814,6 +1814,32 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if not + set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -3105,6 +3131,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -5093,6 +5146,22 @@ spec: required: - key type: object + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -7072,6 +7141,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -7712,6 +7797,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -8402,6 +8503,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -9741,6 +9858,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -10473,6 +10606,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -11122,6 +11271,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -13185,6 +13350,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -13819,6 +14000,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -16626,6 +16823,32 @@ spec: required: - key type: object + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if not + set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -20728,6 +20951,35 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the plugin + defined configuration for the artifact + driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact driver + connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the + artifact repository where the artifact + resides + type: string + name: + description: Name is the name of the + artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -22066,6 +22318,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration is + the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in + the artifact repository where + the artifact resides + type: string + name: + description: Name is the name + of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -23410,6 +23692,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -26052,6 +26361,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -27382,6 +27718,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -28612,6 +28975,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -32945,6 +33335,34 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the plugin + defined configuration for the artifact + driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact driver + connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -34248,6 +34666,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration is the + plugin defined configuration for + the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in + the artifact repository where + the artifact resides + type: string + name: + description: Name is the name of + the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -39286,6 +39734,18 @@ spec: useSDKCreds: type: boolean type: object + plugin: + properties: + configuration: + type: string + keyFormat: + type: string + name: + type: string + required: + - configuration + - name + type: object s3: properties: accessKeySecret: @@ -39895,6 +40355,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -40547,6 +41023,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -41219,6 +41711,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -43054,6 +43562,22 @@ spec: required: - key type: object + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -45033,6 +45557,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -45673,6 +46213,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -46363,6 +46919,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -47702,6 +48274,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -48434,6 +49022,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -49083,6 +49687,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -51146,6 +51766,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -51780,6 +52416,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -53811,6 +54463,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -54506,6 +55174,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -55920,6 +56604,22 @@ spec: required: - key type: object + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -57899,6 +58599,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -58539,6 +59255,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -59229,6 +59961,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -60568,6 +61316,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -61300,6 +62064,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -61949,6 +62729,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -64012,6 +64808,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -64646,6 +65458,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -66625,6 +67453,22 @@ spec: required: - key type: object + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -68604,6 +69448,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -69244,6 +70104,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -69934,6 +70810,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -71273,6 +72165,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -72005,6 +72913,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -72654,6 +73578,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -74717,6 +75657,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: @@ -75351,6 +76307,22 @@ spec: type: object path: type: string + plugin: + properties: + configuration: + type: string + connectionTimeoutSeconds: + format: int32 + type: integer + key: + type: string + name: + type: string + required: + - configuration + - key + - name + type: object raw: properties: data: diff --git a/manifests/base/crds/full/argoproj.io_workflowtaskresults.yaml b/manifests/base/crds/full/argoproj.io_workflowtaskresults.yaml index 6472182fd7cb..61a0747ff309 100644 --- a/manifests/base/crds/full/argoproj.io_workflowtaskresults.yaml +++ b/manifests/base/crds/full/argoproj.io_workflowtaskresults.yaml @@ -868,6 +868,30 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout for + the artifact driver connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: diff --git a/manifests/base/crds/full/argoproj.io_workflowtasksets.yaml b/manifests/base/crds/full/argoproj.io_workflowtasksets.yaml index 9f8d064c84c3..819025d758cb 100644 --- a/manifests/base/crds/full/argoproj.io_workflowtasksets.yaml +++ b/manifests/base/crds/full/argoproj.io_workflowtasksets.yaml @@ -1718,6 +1718,32 @@ spec: required: - key type: object + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if not + set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -5822,6 +5848,35 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the plugin + defined configuration for the artifact + driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact driver + connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the + artifact repository where the artifact + resides + type: string + name: + description: Name is the name of the + artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -7160,6 +7215,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration is + the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in + the artifact repository where + the artifact resides + type: string + name: + description: Name is the name + of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -8504,6 +8589,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -11146,6 +11258,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -12476,6 +12615,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -13706,6 +13872,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -18066,6 +18259,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the + plugin defined configuration for + the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in the + artifact repository where the artifact + resides + type: string + name: + description: Name is the name of the + artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -19416,6 +19639,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration is + the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path + in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name + of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -22771,6 +23024,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: diff --git a/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml b/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml index d5dc17f20390..c5312ac70e5e 100644 --- a/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml +++ b/manifests/base/crds/full/argoproj.io_workflowtemplates.yaml @@ -1799,6 +1799,32 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if not + set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -3090,6 +3116,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -5900,6 +5953,30 @@ spec: required: - key type: object + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout for + the artifact driver connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -9993,6 +10070,34 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the plugin + defined configuration for the artifact + driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact driver + connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -11306,6 +11411,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration is the + plugin defined configuration for + the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in + the artifact repository where + the artifact resides + type: string + name: + description: Name is the name of + the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -12637,6 +12772,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -15268,6 +15430,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -16589,6 +16778,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -17808,6 +18024,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -22131,6 +22374,34 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the plugin + defined configuration for the artifact + driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is + the timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -23403,6 +23674,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the + plugin defined configuration for + the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in the + artifact repository where the artifact + resides + type: string + name: + description: Name is the name of the + artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -27548,6 +27849,32 @@ spec: required: - key type: object + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if not + set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -31650,6 +31977,35 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the plugin + defined configuration for the artifact + driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact driver + connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the + artifact repository where the artifact + resides + type: string + name: + description: Name is the name of the + artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -32988,6 +33344,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration is + the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in + the artifact repository where + the artifact resides + type: string + name: + description: Name is the name + of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -34332,6 +34718,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -36974,6 +37387,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -38304,6 +38744,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -39534,6 +40001,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the + timeout for the artifact driver connection, + 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -43867,6 +44361,34 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact + location details + properties: + configuration: + description: Configuration is the plugin + defined configuration for the artifact + driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact driver + connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact + repository where the artifact resides + type: string + name: + description: Name is the name of the artifact + driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details @@ -45170,6 +45692,36 @@ spec: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin + artifact location details + properties: + configuration: + description: Configuration is the + plugin defined configuration for + the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds + is the timeout for the artifact + driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in + the artifact repository where + the artifact resides + type: string + name: + description: Name is the name of + the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details diff --git a/manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml b/manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml index 11b7fd58ffc3..27cb36b4a54e 100644 --- a/manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml +++ b/manifests/base/crds/minimal/argoproj.io_workflowartifactgctasks.yaml @@ -781,6 +781,32 @@ spec: required: - key type: object + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if not + set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -1816,6 +1842,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: diff --git a/manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml b/manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml index 0cb7e0748c0f..668c565994c8 100644 --- a/manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml +++ b/manifests/base/crds/minimal/argoproj.io_workfloweventbindings.yaml @@ -897,6 +897,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: diff --git a/manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml b/manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml index 6472182fd7cb..61a0747ff309 100644 --- a/manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml +++ b/manifests/base/crds/minimal/argoproj.io_workflowtaskresults.yaml @@ -868,6 +868,30 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout for + the artifact driver connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: diff --git a/manifests/quick-start-minimal.yaml b/manifests/quick-start-minimal.yaml index 5ef470cb28a8..da1893e41ce4 100644 --- a/manifests/quick-start-minimal.yaml +++ b/manifests/quick-start-minimal.yaml @@ -884,6 +884,32 @@ spec: required: - key type: object + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if not + set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -1919,6 +1945,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -3074,6 +3127,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -4377,6 +4457,30 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout for + the artifact driver connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -4922,10 +5026,12 @@ rules: - "" resources: - pods + - secrets verbs: - create - get - patch + - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role @@ -5419,16 +5525,19 @@ subjects: apiVersion: v1 data: artifactRepository: | - s3: - bucket: my-bucket - endpoint: minio:9000 - insecure: true - accessKeySecret: - name: my-minio-cred - key: accesskey - secretKeySecret: - name: my-minio-cred - key: secretkey + archiveLogs: true + plugin: + name: test + configuration: | + bucket: my-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey columns: | - name: Workflow Completed type: label @@ -5501,6 +5610,20 @@ data: secretKeySecret: name: my-minio-cred key: secretkey + plugin-v1: | + archiveLogs: true + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey kind: ConfigMap metadata: annotations: diff --git a/manifests/quick-start-mysql.yaml b/manifests/quick-start-mysql.yaml index 1eec707c19ae..fabe1f50b120 100644 --- a/manifests/quick-start-mysql.yaml +++ b/manifests/quick-start-mysql.yaml @@ -884,6 +884,32 @@ spec: required: - key type: object + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if not + set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -1919,6 +1945,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -3074,6 +3127,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -4377,6 +4457,30 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout for + the artifact driver connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -4922,10 +5026,12 @@ rules: - "" resources: - pods + - secrets verbs: - create - get - patch + - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role @@ -5419,16 +5525,19 @@ subjects: apiVersion: v1 data: artifactRepository: | - s3: - bucket: my-bucket - endpoint: minio:9000 - insecure: true - accessKeySecret: - name: my-minio-cred - key: accesskey - secretKeySecret: - name: my-minio-cred - key: secretkey + archiveLogs: true + plugin: + name: test + configuration: | + bucket: my-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey columns: | - name: Workflow Completed type: label @@ -5541,6 +5650,20 @@ data: secretKeySecret: name: my-minio-cred key: secretkey + plugin-v1: | + archiveLogs: true + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey kind: ConfigMap metadata: annotations: diff --git a/manifests/quick-start-postgres.yaml b/manifests/quick-start-postgres.yaml index 1d737b873e42..eaf3d071dfa5 100644 --- a/manifests/quick-start-postgres.yaml +++ b/manifests/quick-start-postgres.yaml @@ -884,6 +884,32 @@ spec: required: - key type: object + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if not + set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -1919,6 +1945,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds if + not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -3074,6 +3127,33 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location + details + properties: + configuration: + description: Configuration is the plugin defined + configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout + for the artifact driver connection, 5 seconds + if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver + plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -4377,6 +4457,30 @@ spec: path: description: Path is the container path to the artifact type: string + plugin: + description: Plugin contains plugin artifact location details + properties: + configuration: + description: Configuration is the plugin defined configuration + for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout for + the artifact driver connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository + where the artifact resides + type: string + name: + description: Name is the name of the artifact driver plugin + type: string + required: + - configuration + - key + - name + type: object raw: description: Raw contains raw artifact location details properties: @@ -4922,10 +5026,12 @@ rules: - "" resources: - pods + - secrets verbs: - create - get - patch + - list --- apiVersion: rbac.authorization.k8s.io/v1 kind: Role @@ -5419,16 +5525,19 @@ subjects: apiVersion: v1 data: artifactRepository: | - s3: - bucket: my-bucket - endpoint: minio:9000 - insecure: true - accessKeySecret: - name: my-minio-cred - key: accesskey - secretKeySecret: - name: my-minio-cred - key: secretkey + archiveLogs: true + plugin: + name: test + configuration: | + bucket: my-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey columns: | - name: Workflow Completed type: label @@ -5540,6 +5649,20 @@ data: secretKeySecret: name: my-minio-cred key: secretkey + plugin-v1: | + archiveLogs: true + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey kind: ConfigMap metadata: annotations: diff --git a/manifests/quick-start/base/artifact-repositories-configmap.yaml b/manifests/quick-start/base/artifact-repositories-configmap.yaml index 603ad3d1d7af..d543a64f0946 100644 --- a/manifests/quick-start/base/artifact-repositories-configmap.yaml +++ b/manifests/quick-start/base/artifact-repositories-configmap.yaml @@ -31,4 +31,18 @@ data: secretKeySecret: name: my-minio-cred key: secretkey + plugin-v1: | + archiveLogs: true + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey empty: "" diff --git a/manifests/quick-start/base/overlays/workflow-controller-configmap.yaml b/manifests/quick-start/base/overlays/workflow-controller-configmap.yaml index fca708bac6f5..747220db5bb6 100644 --- a/manifests/quick-start/base/overlays/workflow-controller-configmap.yaml +++ b/manifests/quick-start/base/overlays/workflow-controller-configmap.yaml @@ -12,16 +12,19 @@ data: docker/whalesay:latest: cmd: [cowsay] artifactRepository: | - s3: - bucket: my-bucket - endpoint: minio:9000 - insecure: true - accessKeySecret: - name: my-minio-cred - key: accesskey - secretKeySecret: - name: my-minio-cred - key: secretkey + archiveLogs: true + plugin: + name: test + configuration: | + bucket: my-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey metricsConfig: | enabled: true path: /metrics diff --git a/manifests/quick-start/base/pod-manager-role.yaml b/manifests/quick-start/base/pod-manager-role.yaml index 7674ff6fe803..88d25c261e9a 100644 --- a/manifests/quick-start/base/pod-manager-role.yaml +++ b/manifests/quick-start/base/pod-manager-role.yaml @@ -11,7 +11,9 @@ rules: - "" resources: - pods + - secrets verbs: - create - get - patch + - list diff --git a/mkdocs.yml b/mkdocs.yml index 450baeba6bbf..76fe8b504146 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -119,6 +119,7 @@ nav: - key-only-artifacts.md - artifact-repository-ref.md - conditional-artifacts-parameters.md + - artifact-plugin.md - Access Control: - service-accounts.md - workflow-rbac.md @@ -162,7 +163,7 @@ nav: - async-pattern.md - client-libraries.md - swagger.md - - Plugins: + - Executor Plugins: - plugins.md - executor_plugins.md - executor_swagger.md @@ -287,6 +288,7 @@ nav: - running-locally.md - doc-changes.md - public-api.md + - artifact-plugin.md - static-code-analysis.md - stress-testing.md - releasing.md diff --git a/pkg/apiclient/artifact/artifact.pb.go b/pkg/apiclient/artifact/artifact.pb.go new file mode 100644 index 000000000000..e9b9dafedc2a --- /dev/null +++ b/pkg/apiclient/artifact/artifact.pb.go @@ -0,0 +1,4049 @@ +// Code generated by protoc-gen-gogo. DO NOT EDIT. +// source: pkg/apiclient/artifact/artifact.proto + +// Artifact Service +// +// Artifact Service API provides GRPC access to artifact operations + +package artifact + +import ( + context "context" + fmt "fmt" + proto "github.com/gogo/protobuf/proto" + _ "google.golang.org/genproto/googleapis/api/annotations" + grpc "google.golang.org/grpc" + codes "google.golang.org/grpc/codes" + status "google.golang.org/grpc/status" + io "io" + math "math" + math_bits "math/bits" +) + +// Reference imports to suppress errors if they are not otherwise used. +var _ = proto.Marshal +var _ = fmt.Errorf +var _ = math.Inf + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the proto package it is being compiled against. +// A compilation error at this line likely means your copy of the +// proto package needs to be updated. +const _ = proto.GoGoProtoPackageIsVersion3 // please upgrade the proto package + +// Plugin Artifact configuration +type PluginArtifact struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Configuration string `protobuf:"bytes,2,opt,name=configuration,proto3" json:"configuration,omitempty"` + ConnectionTimeoutSeconds int32 `protobuf:"varint,3,opt,name=connection_timeout_seconds,json=connectionTimeoutSeconds,proto3" json:"connection_timeout_seconds,omitempty"` + Key string `protobuf:"bytes,4,opt,name=key,proto3" json:"key,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *PluginArtifact) Reset() { *m = PluginArtifact{} } +func (m *PluginArtifact) String() string { return proto.CompactTextString(m) } +func (*PluginArtifact) ProtoMessage() {} +func (*PluginArtifact) Descriptor() ([]byte, []int) { + return fileDescriptor_a89d6010ce1ebcb2, []int{0} +} +func (m *PluginArtifact) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PluginArtifact) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_PluginArtifact.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *PluginArtifact) XXX_Merge(src proto.Message) { + xxx_messageInfo_PluginArtifact.Merge(m, src) +} +func (m *PluginArtifact) XXX_Size() int { + return m.Size() +} +func (m *PluginArtifact) XXX_DiscardUnknown() { + xxx_messageInfo_PluginArtifact.DiscardUnknown(m) +} + +var xxx_messageInfo_PluginArtifact proto.InternalMessageInfo + +func (m *PluginArtifact) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *PluginArtifact) GetConfiguration() string { + if m != nil { + return m.Configuration + } + return "" +} + +func (m *PluginArtifact) GetConnectionTimeoutSeconds() int32 { + if m != nil { + return m.ConnectionTimeoutSeconds + } + return 0 +} + +func (m *PluginArtifact) GetKey() string { + if m != nil { + return m.Key + } + return "" +} + +// Artifact representation for gRPC +type Artifact struct { + Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + Mode int32 `protobuf:"varint,3,opt,name=mode,proto3" json:"mode,omitempty"` + From string `protobuf:"bytes,4,opt,name=from,proto3" json:"from,omitempty"` + Plugin *PluginArtifact `protobuf:"bytes,5,opt,name=plugin,proto3" json:"plugin,omitempty"` + Optional bool `protobuf:"varint,6,opt,name=optional,proto3" json:"optional,omitempty"` + SubPath string `protobuf:"bytes,7,opt,name=sub_path,json=subPath,proto3" json:"sub_path,omitempty"` + RecurseMode bool `protobuf:"varint,8,opt,name=recurse_mode,json=recurseMode,proto3" json:"recurse_mode,omitempty"` + FromExpression string `protobuf:"bytes,9,opt,name=from_expression,json=fromExpression,proto3" json:"from_expression,omitempty"` + Deleted bool `protobuf:"varint,10,opt,name=deleted,proto3" json:"deleted,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *Artifact) Reset() { *m = Artifact{} } +func (m *Artifact) String() string { return proto.CompactTextString(m) } +func (*Artifact) ProtoMessage() {} +func (*Artifact) Descriptor() ([]byte, []int) { + return fileDescriptor_a89d6010ce1ebcb2, []int{1} +} +func (m *Artifact) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *Artifact) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_Artifact.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *Artifact) XXX_Merge(src proto.Message) { + xxx_messageInfo_Artifact.Merge(m, src) +} +func (m *Artifact) XXX_Size() int { + return m.Size() +} +func (m *Artifact) XXX_DiscardUnknown() { + xxx_messageInfo_Artifact.DiscardUnknown(m) +} + +var xxx_messageInfo_Artifact proto.InternalMessageInfo + +func (m *Artifact) GetName() string { + if m != nil { + return m.Name + } + return "" +} + +func (m *Artifact) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func (m *Artifact) GetMode() int32 { + if m != nil { + return m.Mode + } + return 0 +} + +func (m *Artifact) GetFrom() string { + if m != nil { + return m.From + } + return "" +} + +func (m *Artifact) GetPlugin() *PluginArtifact { + if m != nil { + return m.Plugin + } + return nil +} + +func (m *Artifact) GetOptional() bool { + if m != nil { + return m.Optional + } + return false +} + +func (m *Artifact) GetSubPath() string { + if m != nil { + return m.SubPath + } + return "" +} + +func (m *Artifact) GetRecurseMode() bool { + if m != nil { + return m.RecurseMode + } + return false +} + +func (m *Artifact) GetFromExpression() string { + if m != nil { + return m.FromExpression + } + return "" +} + +func (m *Artifact) GetDeleted() bool { + if m != nil { + return m.Deleted + } + return false +} + +type LoadArtifactRequest struct { + InputArtifact *Artifact `protobuf:"bytes,1,opt,name=input_artifact,json=inputArtifact,proto3" json:"input_artifact,omitempty"` + Path string `protobuf:"bytes,2,opt,name=path,proto3" json:"path,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LoadArtifactRequest) Reset() { *m = LoadArtifactRequest{} } +func (m *LoadArtifactRequest) String() string { return proto.CompactTextString(m) } +func (*LoadArtifactRequest) ProtoMessage() {} +func (*LoadArtifactRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a89d6010ce1ebcb2, []int{2} +} +func (m *LoadArtifactRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LoadArtifactRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LoadArtifactRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *LoadArtifactRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_LoadArtifactRequest.Merge(m, src) +} +func (m *LoadArtifactRequest) XXX_Size() int { + return m.Size() +} +func (m *LoadArtifactRequest) XXX_DiscardUnknown() { + xxx_messageInfo_LoadArtifactRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_LoadArtifactRequest proto.InternalMessageInfo + +func (m *LoadArtifactRequest) GetInputArtifact() *Artifact { + if m != nil { + return m.InputArtifact + } + return nil +} + +func (m *LoadArtifactRequest) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +type LoadArtifactResponse struct { + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *LoadArtifactResponse) Reset() { *m = LoadArtifactResponse{} } +func (m *LoadArtifactResponse) String() string { return proto.CompactTextString(m) } +func (*LoadArtifactResponse) ProtoMessage() {} +func (*LoadArtifactResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a89d6010ce1ebcb2, []int{3} +} +func (m *LoadArtifactResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *LoadArtifactResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_LoadArtifactResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *LoadArtifactResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_LoadArtifactResponse.Merge(m, src) +} +func (m *LoadArtifactResponse) XXX_Size() int { + return m.Size() +} +func (m *LoadArtifactResponse) XXX_DiscardUnknown() { + xxx_messageInfo_LoadArtifactResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_LoadArtifactResponse proto.InternalMessageInfo + +func (m *LoadArtifactResponse) GetSuccess() bool { + if m != nil { + return m.Success + } + return false +} + +func (m *LoadArtifactResponse) GetError() string { + if m != nil { + return m.Error + } + return "" +} + +type OpenStreamRequest struct { + Artifact *Artifact `protobuf:"bytes,1,opt,name=artifact,proto3" json:"artifact,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *OpenStreamRequest) Reset() { *m = OpenStreamRequest{} } +func (m *OpenStreamRequest) String() string { return proto.CompactTextString(m) } +func (*OpenStreamRequest) ProtoMessage() {} +func (*OpenStreamRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a89d6010ce1ebcb2, []int{4} +} +func (m *OpenStreamRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OpenStreamRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OpenStreamRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *OpenStreamRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_OpenStreamRequest.Merge(m, src) +} +func (m *OpenStreamRequest) XXX_Size() int { + return m.Size() +} +func (m *OpenStreamRequest) XXX_DiscardUnknown() { + xxx_messageInfo_OpenStreamRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_OpenStreamRequest proto.InternalMessageInfo + +func (m *OpenStreamRequest) GetArtifact() *Artifact { + if m != nil { + return m.Artifact + } + return nil +} + +type OpenStreamResponse struct { + Data []byte `protobuf:"bytes,1,opt,name=data,proto3" json:"data,omitempty"` + IsEnd bool `protobuf:"varint,2,opt,name=is_end,json=isEnd,proto3" json:"is_end,omitempty"` + Error string `protobuf:"bytes,3,opt,name=error,proto3" json:"error,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *OpenStreamResponse) Reset() { *m = OpenStreamResponse{} } +func (m *OpenStreamResponse) String() string { return proto.CompactTextString(m) } +func (*OpenStreamResponse) ProtoMessage() {} +func (*OpenStreamResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a89d6010ce1ebcb2, []int{5} +} +func (m *OpenStreamResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *OpenStreamResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_OpenStreamResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *OpenStreamResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_OpenStreamResponse.Merge(m, src) +} +func (m *OpenStreamResponse) XXX_Size() int { + return m.Size() +} +func (m *OpenStreamResponse) XXX_DiscardUnknown() { + xxx_messageInfo_OpenStreamResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_OpenStreamResponse proto.InternalMessageInfo + +func (m *OpenStreamResponse) GetData() []byte { + if m != nil { + return m.Data + } + return nil +} + +func (m *OpenStreamResponse) GetIsEnd() bool { + if m != nil { + return m.IsEnd + } + return false +} + +func (m *OpenStreamResponse) GetError() string { + if m != nil { + return m.Error + } + return "" +} + +type SaveArtifactRequest struct { + Path string `protobuf:"bytes,1,opt,name=path,proto3" json:"path,omitempty"` + OutputArtifact *Artifact `protobuf:"bytes,2,opt,name=output_artifact,json=outputArtifact,proto3" json:"output_artifact,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SaveArtifactRequest) Reset() { *m = SaveArtifactRequest{} } +func (m *SaveArtifactRequest) String() string { return proto.CompactTextString(m) } +func (*SaveArtifactRequest) ProtoMessage() {} +func (*SaveArtifactRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a89d6010ce1ebcb2, []int{6} +} +func (m *SaveArtifactRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SaveArtifactRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SaveArtifactRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SaveArtifactRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_SaveArtifactRequest.Merge(m, src) +} +func (m *SaveArtifactRequest) XXX_Size() int { + return m.Size() +} +func (m *SaveArtifactRequest) XXX_DiscardUnknown() { + xxx_messageInfo_SaveArtifactRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_SaveArtifactRequest proto.InternalMessageInfo + +func (m *SaveArtifactRequest) GetPath() string { + if m != nil { + return m.Path + } + return "" +} + +func (m *SaveArtifactRequest) GetOutputArtifact() *Artifact { + if m != nil { + return m.OutputArtifact + } + return nil +} + +type SaveArtifactResponse struct { + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *SaveArtifactResponse) Reset() { *m = SaveArtifactResponse{} } +func (m *SaveArtifactResponse) String() string { return proto.CompactTextString(m) } +func (*SaveArtifactResponse) ProtoMessage() {} +func (*SaveArtifactResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a89d6010ce1ebcb2, []int{7} +} +func (m *SaveArtifactResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SaveArtifactResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_SaveArtifactResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *SaveArtifactResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_SaveArtifactResponse.Merge(m, src) +} +func (m *SaveArtifactResponse) XXX_Size() int { + return m.Size() +} +func (m *SaveArtifactResponse) XXX_DiscardUnknown() { + xxx_messageInfo_SaveArtifactResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_SaveArtifactResponse proto.InternalMessageInfo + +func (m *SaveArtifactResponse) GetSuccess() bool { + if m != nil { + return m.Success + } + return false +} + +func (m *SaveArtifactResponse) GetError() string { + if m != nil { + return m.Error + } + return "" +} + +type DeleteArtifactRequest struct { + Artifact *Artifact `protobuf:"bytes,1,opt,name=artifact,proto3" json:"artifact,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteArtifactRequest) Reset() { *m = DeleteArtifactRequest{} } +func (m *DeleteArtifactRequest) String() string { return proto.CompactTextString(m) } +func (*DeleteArtifactRequest) ProtoMessage() {} +func (*DeleteArtifactRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a89d6010ce1ebcb2, []int{8} +} +func (m *DeleteArtifactRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DeleteArtifactRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DeleteArtifactRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DeleteArtifactRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteArtifactRequest.Merge(m, src) +} +func (m *DeleteArtifactRequest) XXX_Size() int { + return m.Size() +} +func (m *DeleteArtifactRequest) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteArtifactRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteArtifactRequest proto.InternalMessageInfo + +func (m *DeleteArtifactRequest) GetArtifact() *Artifact { + if m != nil { + return m.Artifact + } + return nil +} + +type DeleteArtifactResponse struct { + Success bool `protobuf:"varint,1,opt,name=success,proto3" json:"success,omitempty"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *DeleteArtifactResponse) Reset() { *m = DeleteArtifactResponse{} } +func (m *DeleteArtifactResponse) String() string { return proto.CompactTextString(m) } +func (*DeleteArtifactResponse) ProtoMessage() {} +func (*DeleteArtifactResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a89d6010ce1ebcb2, []int{9} +} +func (m *DeleteArtifactResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *DeleteArtifactResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_DeleteArtifactResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *DeleteArtifactResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_DeleteArtifactResponse.Merge(m, src) +} +func (m *DeleteArtifactResponse) XXX_Size() int { + return m.Size() +} +func (m *DeleteArtifactResponse) XXX_DiscardUnknown() { + xxx_messageInfo_DeleteArtifactResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_DeleteArtifactResponse proto.InternalMessageInfo + +func (m *DeleteArtifactResponse) GetSuccess() bool { + if m != nil { + return m.Success + } + return false +} + +func (m *DeleteArtifactResponse) GetError() string { + if m != nil { + return m.Error + } + return "" +} + +type ListObjectsRequest struct { + Artifact *Artifact `protobuf:"bytes,1,opt,name=artifact,proto3" json:"artifact,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ListObjectsRequest) Reset() { *m = ListObjectsRequest{} } +func (m *ListObjectsRequest) String() string { return proto.CompactTextString(m) } +func (*ListObjectsRequest) ProtoMessage() {} +func (*ListObjectsRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a89d6010ce1ebcb2, []int{10} +} +func (m *ListObjectsRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ListObjectsRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ListObjectsRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ListObjectsRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_ListObjectsRequest.Merge(m, src) +} +func (m *ListObjectsRequest) XXX_Size() int { + return m.Size() +} +func (m *ListObjectsRequest) XXX_DiscardUnknown() { + xxx_messageInfo_ListObjectsRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_ListObjectsRequest proto.InternalMessageInfo + +func (m *ListObjectsRequest) GetArtifact() *Artifact { + if m != nil { + return m.Artifact + } + return nil +} + +type ListObjectsResponse struct { + Objects []string `protobuf:"bytes,1,rep,name=objects,proto3" json:"objects,omitempty"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *ListObjectsResponse) Reset() { *m = ListObjectsResponse{} } +func (m *ListObjectsResponse) String() string { return proto.CompactTextString(m) } +func (*ListObjectsResponse) ProtoMessage() {} +func (*ListObjectsResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a89d6010ce1ebcb2, []int{11} +} +func (m *ListObjectsResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *ListObjectsResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_ListObjectsResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *ListObjectsResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_ListObjectsResponse.Merge(m, src) +} +func (m *ListObjectsResponse) XXX_Size() int { + return m.Size() +} +func (m *ListObjectsResponse) XXX_DiscardUnknown() { + xxx_messageInfo_ListObjectsResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_ListObjectsResponse proto.InternalMessageInfo + +func (m *ListObjectsResponse) GetObjects() []string { + if m != nil { + return m.Objects + } + return nil +} + +func (m *ListObjectsResponse) GetError() string { + if m != nil { + return m.Error + } + return "" +} + +type IsDirectoryRequest struct { + Artifact *Artifact `protobuf:"bytes,1,opt,name=artifact,proto3" json:"artifact,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IsDirectoryRequest) Reset() { *m = IsDirectoryRequest{} } +func (m *IsDirectoryRequest) String() string { return proto.CompactTextString(m) } +func (*IsDirectoryRequest) ProtoMessage() {} +func (*IsDirectoryRequest) Descriptor() ([]byte, []int) { + return fileDescriptor_a89d6010ce1ebcb2, []int{12} +} +func (m *IsDirectoryRequest) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IsDirectoryRequest) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_IsDirectoryRequest.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *IsDirectoryRequest) XXX_Merge(src proto.Message) { + xxx_messageInfo_IsDirectoryRequest.Merge(m, src) +} +func (m *IsDirectoryRequest) XXX_Size() int { + return m.Size() +} +func (m *IsDirectoryRequest) XXX_DiscardUnknown() { + xxx_messageInfo_IsDirectoryRequest.DiscardUnknown(m) +} + +var xxx_messageInfo_IsDirectoryRequest proto.InternalMessageInfo + +func (m *IsDirectoryRequest) GetArtifact() *Artifact { + if m != nil { + return m.Artifact + } + return nil +} + +type IsDirectoryResponse struct { + IsDirectory bool `protobuf:"varint,1,opt,name=is_directory,json=isDirectory,proto3" json:"is_directory,omitempty"` + Error string `protobuf:"bytes,2,opt,name=error,proto3" json:"error,omitempty"` + XXX_NoUnkeyedLiteral struct{} `json:"-"` + XXX_unrecognized []byte `json:"-"` + XXX_sizecache int32 `json:"-"` +} + +func (m *IsDirectoryResponse) Reset() { *m = IsDirectoryResponse{} } +func (m *IsDirectoryResponse) String() string { return proto.CompactTextString(m) } +func (*IsDirectoryResponse) ProtoMessage() {} +func (*IsDirectoryResponse) Descriptor() ([]byte, []int) { + return fileDescriptor_a89d6010ce1ebcb2, []int{13} +} +func (m *IsDirectoryResponse) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *IsDirectoryResponse) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + if deterministic { + return xxx_messageInfo_IsDirectoryResponse.Marshal(b, m, deterministic) + } else { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil + } +} +func (m *IsDirectoryResponse) XXX_Merge(src proto.Message) { + xxx_messageInfo_IsDirectoryResponse.Merge(m, src) +} +func (m *IsDirectoryResponse) XXX_Size() int { + return m.Size() +} +func (m *IsDirectoryResponse) XXX_DiscardUnknown() { + xxx_messageInfo_IsDirectoryResponse.DiscardUnknown(m) +} + +var xxx_messageInfo_IsDirectoryResponse proto.InternalMessageInfo + +func (m *IsDirectoryResponse) GetIsDirectory() bool { + if m != nil { + return m.IsDirectory + } + return false +} + +func (m *IsDirectoryResponse) GetError() string { + if m != nil { + return m.Error + } + return "" +} + +func init() { + proto.RegisterType((*PluginArtifact)(nil), "artifact.PluginArtifact") + proto.RegisterType((*Artifact)(nil), "artifact.Artifact") + proto.RegisterType((*LoadArtifactRequest)(nil), "artifact.LoadArtifactRequest") + proto.RegisterType((*LoadArtifactResponse)(nil), "artifact.LoadArtifactResponse") + proto.RegisterType((*OpenStreamRequest)(nil), "artifact.OpenStreamRequest") + proto.RegisterType((*OpenStreamResponse)(nil), "artifact.OpenStreamResponse") + proto.RegisterType((*SaveArtifactRequest)(nil), "artifact.SaveArtifactRequest") + proto.RegisterType((*SaveArtifactResponse)(nil), "artifact.SaveArtifactResponse") + proto.RegisterType((*DeleteArtifactRequest)(nil), "artifact.DeleteArtifactRequest") + proto.RegisterType((*DeleteArtifactResponse)(nil), "artifact.DeleteArtifactResponse") + proto.RegisterType((*ListObjectsRequest)(nil), "artifact.ListObjectsRequest") + proto.RegisterType((*ListObjectsResponse)(nil), "artifact.ListObjectsResponse") + proto.RegisterType((*IsDirectoryRequest)(nil), "artifact.IsDirectoryRequest") + proto.RegisterType((*IsDirectoryResponse)(nil), "artifact.IsDirectoryResponse") +} + +func init() { + proto.RegisterFile("pkg/apiclient/artifact/artifact.proto", fileDescriptor_a89d6010ce1ebcb2) +} + +var fileDescriptor_a89d6010ce1ebcb2 = []byte{ + // 830 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0x9c, 0x56, 0xcd, 0x72, 0x1b, 0x45, + 0x10, 0xae, 0xd5, 0x9f, 0x37, 0x2d, 0x47, 0x86, 0x51, 0x92, 0x5a, 0x94, 0x58, 0xc8, 0x1b, 0x28, + 0x84, 0xab, 0x22, 0x05, 0x73, 0x8a, 0xe1, 0x02, 0xd8, 0x04, 0xaa, 0x02, 0x49, 0x49, 0x70, 0xe1, + 0xb2, 0x35, 0xda, 0x1d, 0xc9, 0x13, 0x4b, 0x33, 0xcb, 0xcc, 0xac, 0x82, 0xaf, 0xbc, 0x02, 0x37, + 0xde, 0x80, 0x03, 0xef, 0xc1, 0x91, 0x2a, 0x5e, 0x80, 0x72, 0xf1, 0x20, 0xd4, 0xcc, 0xfe, 0x4a, + 0x5a, 0x19, 0xa3, 0x5b, 0x77, 0x4f, 0x4f, 0x7f, 0x5f, 0x7f, 0xea, 0x5e, 0x0d, 0xbc, 0x1f, 0x5e, + 0xce, 0x86, 0x38, 0xa4, 0xfe, 0x9c, 0x12, 0xa6, 0x86, 0x58, 0x28, 0x3a, 0xc5, 0x7e, 0x6e, 0x0c, + 0x42, 0xc1, 0x15, 0x47, 0x76, 0xea, 0x77, 0x1e, 0xcd, 0x38, 0x9f, 0xcd, 0x89, 0xbe, 0x33, 0xc4, + 0x8c, 0x71, 0x85, 0x15, 0xe5, 0x4c, 0xc6, 0x79, 0xee, 0xaf, 0x16, 0xb4, 0x5e, 0xcd, 0xa3, 0x19, + 0x65, 0x9f, 0x25, 0x17, 0x10, 0x82, 0x1a, 0xc3, 0x0b, 0xe2, 0x58, 0x3d, 0xab, 0x7f, 0x67, 0x64, + 0x6c, 0xf4, 0x1e, 0xdc, 0xf5, 0x39, 0x9b, 0xd2, 0x59, 0x24, 0xcc, 0x75, 0xa7, 0x62, 0x0e, 0x57, + 0x83, 0xe8, 0x53, 0xe8, 0xf8, 0x9c, 0x31, 0xe2, 0x6b, 0xcf, 0x53, 0x74, 0x41, 0x78, 0xa4, 0x3c, + 0x49, 0x7c, 0xce, 0x02, 0xe9, 0x54, 0x7b, 0x56, 0xbf, 0x3e, 0x72, 0xf2, 0x8c, 0xef, 0xe2, 0x84, + 0x71, 0x7c, 0x8e, 0xde, 0x82, 0xea, 0x25, 0xb9, 0x72, 0x6a, 0xa6, 0xb2, 0x36, 0xdd, 0xdf, 0x2a, + 0x60, 0xdf, 0x48, 0x0b, 0x41, 0x2d, 0xc4, 0xea, 0x22, 0x61, 0x63, 0x6c, 0x1d, 0x5b, 0xf0, 0x80, + 0x24, 0x70, 0xc6, 0xd6, 0xb1, 0xa9, 0xe0, 0x8b, 0xa4, 0xb6, 0xb1, 0xd1, 0x53, 0x68, 0x84, 0xa6, + 0x71, 0xa7, 0xde, 0xb3, 0xfa, 0xcd, 0x13, 0x67, 0x90, 0x49, 0xb8, 0x2a, 0xc8, 0x28, 0xc9, 0x43, + 0x1d, 0xb0, 0x79, 0xa8, 0x89, 0xe3, 0xb9, 0xd3, 0xe8, 0x59, 0x7d, 0x7b, 0x94, 0xf9, 0xe8, 0x1d, + 0xb0, 0x65, 0x34, 0xf1, 0x0c, 0x9b, 0x3d, 0x83, 0xb2, 0x27, 0xa3, 0xc9, 0x2b, 0x4d, 0xe8, 0x08, + 0xf6, 0x05, 0xf1, 0x23, 0x21, 0x89, 0x67, 0x88, 0xd9, 0xe6, 0x6a, 0x33, 0x89, 0x7d, 0xa3, 0xf9, + 0x7d, 0x00, 0x07, 0x9a, 0x93, 0x47, 0x7e, 0x0a, 0x05, 0x91, 0x52, 0x0b, 0x7c, 0xc7, 0x14, 0x69, + 0xe9, 0xf0, 0x79, 0x16, 0x45, 0x0e, 0xec, 0x05, 0x64, 0x4e, 0x14, 0x09, 0x1c, 0x30, 0x65, 0x52, + 0xd7, 0x0d, 0xa0, 0xfd, 0x82, 0xe3, 0x20, 0x23, 0x4d, 0x7e, 0x8c, 0x88, 0x54, 0xe8, 0x19, 0xb4, + 0x28, 0x0b, 0x23, 0xe5, 0xa5, 0xcd, 0x19, 0xfd, 0x9a, 0x27, 0x28, 0xef, 0x36, 0xbb, 0x72, 0xd7, + 0x64, 0x16, 0x05, 0x5f, 0x17, 0xd7, 0xfd, 0x12, 0xee, 0xad, 0xa2, 0xc8, 0x90, 0x33, 0x49, 0x34, + 0x2f, 0x19, 0xf9, 0x3e, 0x91, 0xd2, 0xd4, 0xb7, 0x47, 0xa9, 0x8b, 0xee, 0x41, 0x9d, 0x08, 0xc1, + 0x45, 0x52, 0x26, 0x76, 0xdc, 0x2f, 0xe0, 0xed, 0x97, 0x21, 0x61, 0x63, 0x25, 0x08, 0x5e, 0xa4, + 0x5c, 0x07, 0x60, 0xdf, 0x82, 0x65, 0x96, 0xe3, 0x7e, 0x0f, 0xa8, 0x58, 0x24, 0xa1, 0x82, 0xa0, + 0x16, 0x60, 0x85, 0x4d, 0x85, 0xfd, 0x91, 0xb1, 0xd1, 0x7d, 0x68, 0x50, 0xe9, 0x11, 0x16, 0x18, + 0x16, 0xf6, 0xa8, 0x4e, 0xe5, 0x39, 0x0b, 0x72, 0x6e, 0xd5, 0x22, 0xb7, 0x29, 0xb4, 0xc7, 0x78, + 0x49, 0xd6, 0x95, 0x4c, 0xe5, 0xb0, 0x0a, 0xb3, 0xf6, 0x09, 0x1c, 0xf0, 0x48, 0xad, 0xc8, 0x5b, + 0xd9, 0x4a, 0xbc, 0x15, 0xa7, 0xa6, 0xbe, 0xd6, 0x72, 0x15, 0x67, 0x47, 0x2d, 0x9f, 0xc3, 0xfd, + 0x33, 0x33, 0x04, 0xeb, 0x8c, 0xff, 0xaf, 0x9e, 0x5f, 0xc1, 0x83, 0xf5, 0x42, 0x3b, 0x52, 0x3a, + 0x03, 0xf4, 0x82, 0x4a, 0xf5, 0x72, 0xf2, 0x9a, 0xf8, 0x4a, 0xee, 0xca, 0xe7, 0x1c, 0xda, 0x2b, + 0x55, 0x72, 0x32, 0x3c, 0x0e, 0x39, 0x56, 0xaf, 0xaa, 0x37, 0x2d, 0x71, 0xb7, 0x93, 0xf9, 0x5a, + 0x9e, 0x51, 0x41, 0x7c, 0xc5, 0xc5, 0xd5, 0xae, 0x64, 0xbe, 0x85, 0xf6, 0x4a, 0x95, 0x84, 0xcc, + 0x11, 0xec, 0x53, 0xe9, 0x05, 0x69, 0x3c, 0x91, 0xa7, 0x49, 0xf3, 0xd4, 0x72, 0x56, 0x27, 0xbf, + 0xd7, 0xe1, 0x20, 0x85, 0x19, 0x13, 0xb1, 0xa4, 0x3e, 0x41, 0x17, 0x50, 0xd3, 0xdb, 0x85, 0x0e, + 0x73, 0x26, 0x25, 0x3b, 0xdd, 0xe9, 0x6e, 0x3b, 0x8e, 0x39, 0xb9, 0x47, 0x3f, 0xff, 0xf5, 0xcf, + 0x2f, 0x95, 0x87, 0xee, 0x03, 0xf3, 0xcd, 0x5f, 0x7e, 0x94, 0xfd, 0x37, 0xc8, 0xe1, 0x9c, 0xe3, + 0xe0, 0xd4, 0x3a, 0x46, 0x0c, 0x20, 0x5f, 0x1d, 0xf4, 0x30, 0x2f, 0xb8, 0xb1, 0x95, 0x9d, 0x47, + 0xe5, 0x87, 0x09, 0xd6, 0x63, 0x83, 0x75, 0xe8, 0x3a, 0x9b, 0x58, 0xd2, 0x64, 0x9e, 0x5a, 0xc7, + 0x4f, 0x2d, 0xdd, 0x99, 0x9e, 0xf5, 0x62, 0x67, 0x25, 0x3b, 0x56, 0xec, 0xac, 0x6c, 0x35, 0x6e, + 0xea, 0x4c, 0xe2, 0x25, 0xd1, 0x9d, 0x85, 0xd0, 0x88, 0x87, 0x18, 0xbd, 0x9b, 0x17, 0x2b, 0xdd, + 0x8f, 0x4e, 0x6f, 0x7b, 0xc2, 0x7f, 0x77, 0x17, 0x7f, 0x77, 0x35, 0xe2, 0x02, 0x9a, 0x85, 0x31, + 0x45, 0x05, 0xbd, 0x36, 0x77, 0xa0, 0x73, 0xb8, 0xe5, 0xf4, 0x16, 0x3f, 0x1d, 0x95, 0x4a, 0xc3, + 0x45, 0xd0, 0x2c, 0x0c, 0x62, 0x11, 0x6e, 0x73, 0xca, 0x8b, 0x70, 0x25, 0xd3, 0xeb, 0x7e, 0x68, + 0xe0, 0x1e, 0xbb, 0xdd, 0x4d, 0x38, 0x2a, 0x9f, 0x64, 0x53, 0x7d, 0x6a, 0x1d, 0x7f, 0xfe, 0xfc, + 0x8f, 0xeb, 0xae, 0xf5, 0xe7, 0x75, 0xd7, 0xfa, 0xfb, 0xba, 0x6b, 0xfd, 0xf0, 0x6c, 0x46, 0xd5, + 0x45, 0x34, 0x19, 0xf8, 0x7c, 0x31, 0xc4, 0x62, 0xc6, 0x43, 0xc1, 0x5f, 0x1b, 0xe3, 0xc9, 0x1b, + 0x2e, 0x2e, 0xa7, 0x73, 0xfe, 0x46, 0x0e, 0xcb, 0x1f, 0x2a, 0x93, 0x86, 0x79, 0x78, 0x7c, 0xfc, + 0x6f, 0x00, 0x00, 0x00, 0xff, 0xff, 0xc3, 0x8f, 0x7f, 0x02, 0xc9, 0x08, 0x00, 0x00, +} + +// Reference imports to suppress errors if they are not otherwise used. +var _ context.Context +var _ grpc.ClientConn + +// This is a compile-time assertion to ensure that this generated file +// is compatible with the grpc package it is being compiled against. +const _ = grpc.SupportPackageIsVersion4 + +// ArtifactServiceClient is the client API for ArtifactService service. +// +// For semantics around ctx use and closing/ending streaming RPCs, please refer to https://godoc.org/google.golang.org/grpc#ClientConn.NewStream. +type ArtifactServiceClient interface { + Load(ctx context.Context, in *LoadArtifactRequest, opts ...grpc.CallOption) (*LoadArtifactResponse, error) + OpenStream(ctx context.Context, in *OpenStreamRequest, opts ...grpc.CallOption) (ArtifactService_OpenStreamClient, error) + Save(ctx context.Context, in *SaveArtifactRequest, opts ...grpc.CallOption) (*SaveArtifactResponse, error) + Delete(ctx context.Context, in *DeleteArtifactRequest, opts ...grpc.CallOption) (*DeleteArtifactResponse, error) + ListObjects(ctx context.Context, in *ListObjectsRequest, opts ...grpc.CallOption) (*ListObjectsResponse, error) + IsDirectory(ctx context.Context, in *IsDirectoryRequest, opts ...grpc.CallOption) (*IsDirectoryResponse, error) +} + +type artifactServiceClient struct { + cc *grpc.ClientConn +} + +func NewArtifactServiceClient(cc *grpc.ClientConn) ArtifactServiceClient { + return &artifactServiceClient{cc} +} + +func (c *artifactServiceClient) Load(ctx context.Context, in *LoadArtifactRequest, opts ...grpc.CallOption) (*LoadArtifactResponse, error) { + out := new(LoadArtifactResponse) + err := c.cc.Invoke(ctx, "/artifact.ArtifactService/Load", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *artifactServiceClient) OpenStream(ctx context.Context, in *OpenStreamRequest, opts ...grpc.CallOption) (ArtifactService_OpenStreamClient, error) { + stream, err := c.cc.NewStream(ctx, &_ArtifactService_serviceDesc.Streams[0], "/artifact.ArtifactService/OpenStream", opts...) + if err != nil { + return nil, err + } + x := &artifactServiceOpenStreamClient{stream} + if err := x.ClientStream.SendMsg(in); err != nil { + return nil, err + } + if err := x.ClientStream.CloseSend(); err != nil { + return nil, err + } + return x, nil +} + +type ArtifactService_OpenStreamClient interface { + Recv() (*OpenStreamResponse, error) + grpc.ClientStream +} + +type artifactServiceOpenStreamClient struct { + grpc.ClientStream +} + +func (x *artifactServiceOpenStreamClient) Recv() (*OpenStreamResponse, error) { + m := new(OpenStreamResponse) + if err := x.ClientStream.RecvMsg(m); err != nil { + return nil, err + } + return m, nil +} + +func (c *artifactServiceClient) Save(ctx context.Context, in *SaveArtifactRequest, opts ...grpc.CallOption) (*SaveArtifactResponse, error) { + out := new(SaveArtifactResponse) + err := c.cc.Invoke(ctx, "/artifact.ArtifactService/Save", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *artifactServiceClient) Delete(ctx context.Context, in *DeleteArtifactRequest, opts ...grpc.CallOption) (*DeleteArtifactResponse, error) { + out := new(DeleteArtifactResponse) + err := c.cc.Invoke(ctx, "/artifact.ArtifactService/Delete", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *artifactServiceClient) ListObjects(ctx context.Context, in *ListObjectsRequest, opts ...grpc.CallOption) (*ListObjectsResponse, error) { + out := new(ListObjectsResponse) + err := c.cc.Invoke(ctx, "/artifact.ArtifactService/ListObjects", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +func (c *artifactServiceClient) IsDirectory(ctx context.Context, in *IsDirectoryRequest, opts ...grpc.CallOption) (*IsDirectoryResponse, error) { + out := new(IsDirectoryResponse) + err := c.cc.Invoke(ctx, "/artifact.ArtifactService/IsDirectory", in, out, opts...) + if err != nil { + return nil, err + } + return out, nil +} + +// ArtifactServiceServer is the server API for ArtifactService service. +type ArtifactServiceServer interface { + Load(context.Context, *LoadArtifactRequest) (*LoadArtifactResponse, error) + OpenStream(*OpenStreamRequest, ArtifactService_OpenStreamServer) error + Save(context.Context, *SaveArtifactRequest) (*SaveArtifactResponse, error) + Delete(context.Context, *DeleteArtifactRequest) (*DeleteArtifactResponse, error) + ListObjects(context.Context, *ListObjectsRequest) (*ListObjectsResponse, error) + IsDirectory(context.Context, *IsDirectoryRequest) (*IsDirectoryResponse, error) +} + +// UnimplementedArtifactServiceServer can be embedded to have forward compatible implementations. +type UnimplementedArtifactServiceServer struct { +} + +func (*UnimplementedArtifactServiceServer) Load(ctx context.Context, req *LoadArtifactRequest) (*LoadArtifactResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Load not implemented") +} +func (*UnimplementedArtifactServiceServer) OpenStream(req *OpenStreamRequest, srv ArtifactService_OpenStreamServer) error { + return status.Errorf(codes.Unimplemented, "method OpenStream not implemented") +} +func (*UnimplementedArtifactServiceServer) Save(ctx context.Context, req *SaveArtifactRequest) (*SaveArtifactResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Save not implemented") +} +func (*UnimplementedArtifactServiceServer) Delete(ctx context.Context, req *DeleteArtifactRequest) (*DeleteArtifactResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method Delete not implemented") +} +func (*UnimplementedArtifactServiceServer) ListObjects(ctx context.Context, req *ListObjectsRequest) (*ListObjectsResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method ListObjects not implemented") +} +func (*UnimplementedArtifactServiceServer) IsDirectory(ctx context.Context, req *IsDirectoryRequest) (*IsDirectoryResponse, error) { + return nil, status.Errorf(codes.Unimplemented, "method IsDirectory not implemented") +} + +func RegisterArtifactServiceServer(s *grpc.Server, srv ArtifactServiceServer) { + s.RegisterService(&_ArtifactService_serviceDesc, srv) +} + +func _ArtifactService_Load_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(LoadArtifactRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ArtifactServiceServer).Load(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/artifact.ArtifactService/Load", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ArtifactServiceServer).Load(ctx, req.(*LoadArtifactRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ArtifactService_OpenStream_Handler(srv interface{}, stream grpc.ServerStream) error { + m := new(OpenStreamRequest) + if err := stream.RecvMsg(m); err != nil { + return err + } + return srv.(ArtifactServiceServer).OpenStream(m, &artifactServiceOpenStreamServer{stream}) +} + +type ArtifactService_OpenStreamServer interface { + Send(*OpenStreamResponse) error + grpc.ServerStream +} + +type artifactServiceOpenStreamServer struct { + grpc.ServerStream +} + +func (x *artifactServiceOpenStreamServer) Send(m *OpenStreamResponse) error { + return x.ServerStream.SendMsg(m) +} + +func _ArtifactService_Save_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(SaveArtifactRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ArtifactServiceServer).Save(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/artifact.ArtifactService/Save", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ArtifactServiceServer).Save(ctx, req.(*SaveArtifactRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ArtifactService_Delete_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(DeleteArtifactRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ArtifactServiceServer).Delete(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/artifact.ArtifactService/Delete", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ArtifactServiceServer).Delete(ctx, req.(*DeleteArtifactRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ArtifactService_ListObjects_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(ListObjectsRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ArtifactServiceServer).ListObjects(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/artifact.ArtifactService/ListObjects", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ArtifactServiceServer).ListObjects(ctx, req.(*ListObjectsRequest)) + } + return interceptor(ctx, in, info, handler) +} + +func _ArtifactService_IsDirectory_Handler(srv interface{}, ctx context.Context, dec func(interface{}) error, interceptor grpc.UnaryServerInterceptor) (interface{}, error) { + in := new(IsDirectoryRequest) + if err := dec(in); err != nil { + return nil, err + } + if interceptor == nil { + return srv.(ArtifactServiceServer).IsDirectory(ctx, in) + } + info := &grpc.UnaryServerInfo{ + Server: srv, + FullMethod: "/artifact.ArtifactService/IsDirectory", + } + handler := func(ctx context.Context, req interface{}) (interface{}, error) { + return srv.(ArtifactServiceServer).IsDirectory(ctx, req.(*IsDirectoryRequest)) + } + return interceptor(ctx, in, info, handler) +} + +var _ArtifactService_serviceDesc = grpc.ServiceDesc{ + ServiceName: "artifact.ArtifactService", + HandlerType: (*ArtifactServiceServer)(nil), + Methods: []grpc.MethodDesc{ + { + MethodName: "Load", + Handler: _ArtifactService_Load_Handler, + }, + { + MethodName: "Save", + Handler: _ArtifactService_Save_Handler, + }, + { + MethodName: "Delete", + Handler: _ArtifactService_Delete_Handler, + }, + { + MethodName: "ListObjects", + Handler: _ArtifactService_ListObjects_Handler, + }, + { + MethodName: "IsDirectory", + Handler: _ArtifactService_IsDirectory_Handler, + }, + }, + Streams: []grpc.StreamDesc{ + { + StreamName: "OpenStream", + Handler: _ArtifactService_OpenStream_Handler, + ServerStreams: true, + }, + }, + Metadata: "pkg/apiclient/artifact/artifact.proto", +} + +func (m *PluginArtifact) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PluginArtifact) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PluginArtifact) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Key) > 0 { + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Key))) + i-- + dAtA[i] = 0x22 + } + if m.ConnectionTimeoutSeconds != 0 { + i = encodeVarintArtifact(dAtA, i, uint64(m.ConnectionTimeoutSeconds)) + i-- + dAtA[i] = 0x18 + } + if len(m.Configuration) > 0 { + i -= len(m.Configuration) + copy(dAtA[i:], m.Configuration) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Configuration))) + i-- + dAtA[i] = 0x12 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *Artifact) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *Artifact) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Artifact) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Deleted { + i-- + if m.Deleted { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x50 + } + if len(m.FromExpression) > 0 { + i -= len(m.FromExpression) + copy(dAtA[i:], m.FromExpression) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.FromExpression))) + i-- + dAtA[i] = 0x4a + } + if m.RecurseMode { + i-- + if m.RecurseMode { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x40 + } + if len(m.SubPath) > 0 { + i -= len(m.SubPath) + copy(dAtA[i:], m.SubPath) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.SubPath))) + i-- + dAtA[i] = 0x3a + } + if m.Optional { + i-- + if m.Optional { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x30 + } + if m.Plugin != nil { + { + size, err := m.Plugin.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintArtifact(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x2a + } + if len(m.From) > 0 { + i -= len(m.From) + copy(dAtA[i:], m.From) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.From))) + i-- + dAtA[i] = 0x22 + } + if m.Mode != 0 { + i = encodeVarintArtifact(dAtA, i, uint64(m.Mode)) + i-- + dAtA[i] = 0x18 + } + if len(m.Path) > 0 { + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Path))) + i-- + dAtA[i] = 0x12 + } + if len(m.Name) > 0 { + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *LoadArtifactRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LoadArtifactRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LoadArtifactRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Path) > 0 { + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Path))) + i-- + dAtA[i] = 0x12 + } + if m.InputArtifact != nil { + { + size, err := m.InputArtifact.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintArtifact(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *LoadArtifactResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *LoadArtifactResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *LoadArtifactResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Error) > 0 { + i -= len(m.Error) + copy(dAtA[i:], m.Error) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Error))) + i-- + dAtA[i] = 0x12 + } + if m.Success { + i-- + if m.Success { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *OpenStreamRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *OpenStreamRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OpenStreamRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Artifact != nil { + { + size, err := m.Artifact.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintArtifact(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *OpenStreamResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *OpenStreamResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *OpenStreamResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Error) > 0 { + i -= len(m.Error) + copy(dAtA[i:], m.Error) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Error))) + i-- + dAtA[i] = 0x1a + } + if m.IsEnd { + i-- + if m.IsEnd { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x10 + } + if len(m.Data) > 0 { + i -= len(m.Data) + copy(dAtA[i:], m.Data) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Data))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SaveArtifactRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SaveArtifactRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SaveArtifactRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.OutputArtifact != nil { + { + size, err := m.OutputArtifact.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintArtifact(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if len(m.Path) > 0 { + i -= len(m.Path) + copy(dAtA[i:], m.Path) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Path))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SaveArtifactResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *SaveArtifactResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SaveArtifactResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Error) > 0 { + i -= len(m.Error) + copy(dAtA[i:], m.Error) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Error))) + i-- + dAtA[i] = 0x12 + } + if m.Success { + i-- + if m.Success { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *DeleteArtifactRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DeleteArtifactRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DeleteArtifactRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Artifact != nil { + { + size, err := m.Artifact.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintArtifact(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *DeleteArtifactResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *DeleteArtifactResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *DeleteArtifactResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Error) > 0 { + i -= len(m.Error) + copy(dAtA[i:], m.Error) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Error))) + i-- + dAtA[i] = 0x12 + } + if m.Success { + i-- + if m.Success { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func (m *ListObjectsRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ListObjectsRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ListObjectsRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Artifact != nil { + { + size, err := m.Artifact.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintArtifact(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *ListObjectsResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *ListObjectsResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *ListObjectsResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Error) > 0 { + i -= len(m.Error) + copy(dAtA[i:], m.Error) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Error))) + i-- + dAtA[i] = 0x12 + } + if len(m.Objects) > 0 { + for iNdEx := len(m.Objects) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.Objects[iNdEx]) + copy(dAtA[i:], m.Objects[iNdEx]) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Objects[iNdEx]))) + i-- + dAtA[i] = 0xa + } + } + return len(dAtA) - i, nil +} + +func (m *IsDirectoryRequest) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IsDirectoryRequest) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IsDirectoryRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if m.Artifact != nil { + { + size, err := m.Artifact.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintArtifact(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *IsDirectoryResponse) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *IsDirectoryResponse) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *IsDirectoryResponse) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.XXX_unrecognized != nil { + i -= len(m.XXX_unrecognized) + copy(dAtA[i:], m.XXX_unrecognized) + } + if len(m.Error) > 0 { + i -= len(m.Error) + copy(dAtA[i:], m.Error) + i = encodeVarintArtifact(dAtA, i, uint64(len(m.Error))) + i-- + dAtA[i] = 0x12 + } + if m.IsDirectory { + i-- + if m.IsDirectory { + dAtA[i] = 1 + } else { + dAtA[i] = 0 + } + i-- + dAtA[i] = 0x8 + } + return len(dAtA) - i, nil +} + +func encodeVarintArtifact(dAtA []byte, offset int, v uint64) int { + offset -= sovArtifact(v) + base := offset + for v >= 1<<7 { + dAtA[offset] = uint8(v&0x7f | 0x80) + v >>= 7 + offset++ + } + dAtA[offset] = uint8(v) + return base +} +func (m *PluginArtifact) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + l = len(m.Configuration) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.ConnectionTimeoutSeconds != 0 { + n += 1 + sovArtifact(uint64(m.ConnectionTimeoutSeconds)) + } + l = len(m.Key) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *Artifact) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + l = len(m.Path) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.Mode != 0 { + n += 1 + sovArtifact(uint64(m.Mode)) + } + l = len(m.From) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.Plugin != nil { + l = m.Plugin.Size() + n += 1 + l + sovArtifact(uint64(l)) + } + if m.Optional { + n += 2 + } + l = len(m.SubPath) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.RecurseMode { + n += 2 + } + l = len(m.FromExpression) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.Deleted { + n += 2 + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *LoadArtifactRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.InputArtifact != nil { + l = m.InputArtifact.Size() + n += 1 + l + sovArtifact(uint64(l)) + } + l = len(m.Path) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *LoadArtifactResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Success { + n += 2 + } + l = len(m.Error) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *OpenStreamRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Artifact != nil { + l = m.Artifact.Size() + n += 1 + l + sovArtifact(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *OpenStreamResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Data) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.IsEnd { + n += 2 + } + l = len(m.Error) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *SaveArtifactRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Path) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.OutputArtifact != nil { + l = m.OutputArtifact.Size() + n += 1 + l + sovArtifact(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *SaveArtifactResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Success { + n += 2 + } + l = len(m.Error) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *DeleteArtifactRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Artifact != nil { + l = m.Artifact.Size() + n += 1 + l + sovArtifact(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *DeleteArtifactResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Success { + n += 2 + } + l = len(m.Error) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ListObjectsRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Artifact != nil { + l = m.Artifact.Size() + n += 1 + l + sovArtifact(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *ListObjectsResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if len(m.Objects) > 0 { + for _, s := range m.Objects { + l = len(s) + n += 1 + l + sovArtifact(uint64(l)) + } + } + l = len(m.Error) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *IsDirectoryRequest) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Artifact != nil { + l = m.Artifact.Size() + n += 1 + l + sovArtifact(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func (m *IsDirectoryResponse) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.IsDirectory { + n += 2 + } + l = len(m.Error) + if l > 0 { + n += 1 + l + sovArtifact(uint64(l)) + } + if m.XXX_unrecognized != nil { + n += len(m.XXX_unrecognized) + } + return n +} + +func sovArtifact(x uint64) (n int) { + return (math_bits.Len64(x|1) + 6) / 7 +} +func sozArtifact(x uint64) (n int) { + return sovArtifact(uint64((x << 1) ^ uint64((int64(x) >> 63)))) +} +func (m *PluginArtifact) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PluginArtifact: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PluginArtifact: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Configuration", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Configuration = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionTimeoutSeconds", wireType) + } + m.ConnectionTimeoutSeconds = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ConnectionTimeoutSeconds |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipArtifact(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthArtifact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *Artifact) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: Artifact: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Artifact: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Mode", wireType) + } + m.Mode = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.Mode |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field From", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.From = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Plugin", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Plugin == nil { + m.Plugin = &PluginArtifact{} + } + if err := m.Plugin.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 6: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Optional", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Optional = bool(v != 0) + case 7: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SubPath", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SubPath = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 8: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field RecurseMode", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.RecurseMode = bool(v != 0) + case 9: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field FromExpression", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.FromExpression = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 10: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Deleted", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Deleted = bool(v != 0) + default: + iNdEx = preIndex + skippy, err := skipArtifact(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthArtifact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LoadArtifactRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LoadArtifactRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LoadArtifactRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InputArtifact", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.InputArtifact == nil { + m.InputArtifact = &Artifact{} + } + if err := m.InputArtifact.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipArtifact(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthArtifact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *LoadArtifactResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: LoadArtifactResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: LoadArtifactResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Success", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Success = bool(v != 0) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Error = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipArtifact(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthArtifact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *OpenStreamRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: OpenStreamRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OpenStreamRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Artifact", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Artifact == nil { + m.Artifact = &Artifact{} + } + if err := m.Artifact.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipArtifact(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthArtifact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *OpenStreamResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: OpenStreamResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: OpenStreamResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Data", wireType) + } + var byteLen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + byteLen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if byteLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + byteLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Data = append(m.Data[:0], dAtA[iNdEx:postIndex]...) + if m.Data == nil { + m.Data = []byte{} + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsEnd", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsEnd = bool(v != 0) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Error = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipArtifact(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthArtifact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SaveArtifactRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SaveArtifactRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SaveArtifactRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Path", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Path = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field OutputArtifact", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.OutputArtifact == nil { + m.OutputArtifact = &Artifact{} + } + if err := m.OutputArtifact.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipArtifact(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthArtifact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *SaveArtifactResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: SaveArtifactResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SaveArtifactResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Success", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Success = bool(v != 0) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Error = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipArtifact(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthArtifact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeleteArtifactRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeleteArtifactRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeleteArtifactRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Artifact", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Artifact == nil { + m.Artifact = &Artifact{} + } + if err := m.Artifact.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipArtifact(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthArtifact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *DeleteArtifactResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: DeleteArtifactResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: DeleteArtifactResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Success", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Success = bool(v != 0) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Error = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipArtifact(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthArtifact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ListObjectsRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ListObjectsRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ListObjectsRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Artifact", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Artifact == nil { + m.Artifact = &Artifact{} + } + if err := m.Artifact.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipArtifact(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthArtifact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *ListObjectsResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: ListObjectsResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: ListObjectsResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Objects", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Objects = append(m.Objects, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Error = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipArtifact(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthArtifact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IsDirectoryRequest) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IsDirectoryRequest: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IsDirectoryRequest: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Artifact", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Artifact == nil { + m.Artifact = &Artifact{} + } + if err := m.Artifact.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipArtifact(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthArtifact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *IsDirectoryResponse) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: IsDirectoryResponse: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: IsDirectoryResponse: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field IsDirectory", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.IsDirectory = bool(v != 0) + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Error", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowArtifact + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthArtifact + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthArtifact + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Error = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipArtifact(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthArtifact + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + m.XXX_unrecognized = append(m.XXX_unrecognized, dAtA[iNdEx:iNdEx+skippy]...) + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func skipArtifact(dAtA []byte) (n int, err error) { + l := len(dAtA) + iNdEx := 0 + depth := 0 + for iNdEx < l { + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowArtifact + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= (uint64(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + wireType := int(wire & 0x7) + switch wireType { + case 0: + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowArtifact + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + iNdEx++ + if dAtA[iNdEx-1] < 0x80 { + break + } + } + case 1: + iNdEx += 8 + case 2: + var length int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return 0, ErrIntOverflowArtifact + } + if iNdEx >= l { + return 0, io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + length |= (int(b) & 0x7F) << shift + if b < 0x80 { + break + } + } + if length < 0 { + return 0, ErrInvalidLengthArtifact + } + iNdEx += length + case 3: + depth++ + case 4: + if depth == 0 { + return 0, ErrUnexpectedEndOfGroupArtifact + } + depth-- + case 5: + iNdEx += 4 + default: + return 0, fmt.Errorf("proto: illegal wireType %d", wireType) + } + if iNdEx < 0 { + return 0, ErrInvalidLengthArtifact + } + if depth == 0 { + return iNdEx, nil + } + } + return 0, io.ErrUnexpectedEOF +} + +var ( + ErrInvalidLengthArtifact = fmt.Errorf("proto: negative length found during unmarshaling") + ErrIntOverflowArtifact = fmt.Errorf("proto: integer overflow") + ErrUnexpectedEndOfGroupArtifact = fmt.Errorf("proto: unexpected end of group") +) diff --git a/pkg/apiclient/artifact/artifact.pb.gw.go b/pkg/apiclient/artifact/artifact.pb.gw.go new file mode 100644 index 000000000000..fe85f7877bd5 --- /dev/null +++ b/pkg/apiclient/artifact/artifact.pb.gw.go @@ -0,0 +1,549 @@ +// Code generated by protoc-gen-grpc-gateway. DO NOT EDIT. +// source: pkg/apiclient/artifact/artifact.proto + +/* +Package artifact is a reverse proxy. + +It translates gRPC into RESTful JSON APIs. +*/ +package artifact + +import ( + "context" + "io" + "net/http" + + "github.com/golang/protobuf/descriptor" + "github.com/golang/protobuf/proto" + "github.com/grpc-ecosystem/grpc-gateway/runtime" + "github.com/grpc-ecosystem/grpc-gateway/utilities" + "google.golang.org/grpc" + "google.golang.org/grpc/codes" + "google.golang.org/grpc/grpclog" + "google.golang.org/grpc/metadata" + "google.golang.org/grpc/status" +) + +// Suppress "imported and not used" errors +var _ codes.Code +var _ io.Reader +var _ status.Status +var _ = runtime.String +var _ = utilities.NewDoubleArray +var _ = descriptor.ForMessage +var _ = metadata.Join + +func request_ArtifactService_Load_0(ctx context.Context, marshaler runtime.Marshaler, client ArtifactServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq LoadArtifactRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Load(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ArtifactService_Load_0(ctx context.Context, marshaler runtime.Marshaler, server ArtifactServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq LoadArtifactRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Load(ctx, &protoReq) + return msg, metadata, err + +} + +func request_ArtifactService_OpenStream_0(ctx context.Context, marshaler runtime.Marshaler, client ArtifactServiceClient, req *http.Request, pathParams map[string]string) (ArtifactService_OpenStreamClient, runtime.ServerMetadata, error) { + var protoReq OpenStreamRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + stream, err := client.OpenStream(ctx, &protoReq) + if err != nil { + return nil, metadata, err + } + header, err := stream.Header() + if err != nil { + return nil, metadata, err + } + metadata.HeaderMD = header + return stream, metadata, nil + +} + +func request_ArtifactService_Save_0(ctx context.Context, marshaler runtime.Marshaler, client ArtifactServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SaveArtifactRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Save(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ArtifactService_Save_0(ctx context.Context, marshaler runtime.Marshaler, server ArtifactServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq SaveArtifactRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Save(ctx, &protoReq) + return msg, metadata, err + +} + +func request_ArtifactService_Delete_0(ctx context.Context, marshaler runtime.Marshaler, client ArtifactServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteArtifactRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.Delete(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ArtifactService_Delete_0(ctx context.Context, marshaler runtime.Marshaler, server ArtifactServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq DeleteArtifactRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.Delete(ctx, &protoReq) + return msg, metadata, err + +} + +func request_ArtifactService_ListObjects_0(ctx context.Context, marshaler runtime.Marshaler, client ArtifactServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListObjectsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.ListObjects(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ArtifactService_ListObjects_0(ctx context.Context, marshaler runtime.Marshaler, server ArtifactServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq ListObjectsRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.ListObjects(ctx, &protoReq) + return msg, metadata, err + +} + +func request_ArtifactService_IsDirectory_0(ctx context.Context, marshaler runtime.Marshaler, client ArtifactServiceClient, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq IsDirectoryRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := client.IsDirectory(ctx, &protoReq, grpc.Header(&metadata.HeaderMD), grpc.Trailer(&metadata.TrailerMD)) + return msg, metadata, err + +} + +func local_request_ArtifactService_IsDirectory_0(ctx context.Context, marshaler runtime.Marshaler, server ArtifactServiceServer, req *http.Request, pathParams map[string]string) (proto.Message, runtime.ServerMetadata, error) { + var protoReq IsDirectoryRequest + var metadata runtime.ServerMetadata + + newReader, berr := utilities.IOReaderFactory(req.Body) + if berr != nil { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", berr) + } + if err := marshaler.NewDecoder(newReader()).Decode(&protoReq); err != nil && err != io.EOF { + return nil, metadata, status.Errorf(codes.InvalidArgument, "%v", err) + } + + msg, err := server.IsDirectory(ctx, &protoReq) + return msg, metadata, err + +} + +// RegisterArtifactServiceHandlerServer registers the http handlers for service ArtifactService to "mux". +// UnaryRPC :call ArtifactServiceServer directly. +// StreamingRPC :currently unsupported pending https://github.com/grpc/grpc-go/issues/906. +// Note that using this registration option will cause many gRPC library features to stop working. Consider using RegisterArtifactServiceHandlerFromEndpoint instead. +func RegisterArtifactServiceHandlerServer(ctx context.Context, mux *runtime.ServeMux, server ArtifactServiceServer) error { + + mux.Handle("POST", pattern_ArtifactService_Load_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ArtifactService_Load_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArtifactService_Load_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ArtifactService_OpenStream_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + err := status.Error(codes.Unimplemented, "streaming calls are not yet supported in the in-process transport") + _, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + }) + + mux.Handle("POST", pattern_ArtifactService_Save_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ArtifactService_Save_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArtifactService_Save_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ArtifactService_Delete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ArtifactService_Delete_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArtifactService_Delete_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ArtifactService_ListObjects_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ArtifactService_ListObjects_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArtifactService_ListObjects_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ArtifactService_IsDirectory_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + var stream runtime.ServerTransportStream + ctx = grpc.NewContextWithServerTransportStream(ctx, &stream) + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateIncomingContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := local_request_ArtifactService_IsDirectory_0(rctx, inboundMarshaler, server, req, pathParams) + md.HeaderMD, md.TrailerMD = metadata.Join(md.HeaderMD, stream.Header()), metadata.Join(md.TrailerMD, stream.Trailer()) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArtifactService_IsDirectory_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +// RegisterArtifactServiceHandlerFromEndpoint is same as RegisterArtifactServiceHandler but +// automatically dials to "endpoint" and closes the connection when "ctx" gets done. +func RegisterArtifactServiceHandlerFromEndpoint(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) (err error) { + conn, err := grpc.Dial(endpoint, opts...) + if err != nil { + return err + } + defer func() { + if err != nil { + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + return + } + go func() { + <-ctx.Done() + if cerr := conn.Close(); cerr != nil { + grpclog.Infof("Failed to close conn to %s: %v", endpoint, cerr) + } + }() + }() + + return RegisterArtifactServiceHandler(ctx, mux, conn) +} + +// RegisterArtifactServiceHandler registers the http handlers for service ArtifactService to "mux". +// The handlers forward requests to the grpc endpoint over "conn". +func RegisterArtifactServiceHandler(ctx context.Context, mux *runtime.ServeMux, conn *grpc.ClientConn) error { + return RegisterArtifactServiceHandlerClient(ctx, mux, NewArtifactServiceClient(conn)) +} + +// RegisterArtifactServiceHandlerClient registers the http handlers for service ArtifactService +// to "mux". The handlers forward requests to the grpc endpoint over the given implementation of "ArtifactServiceClient". +// Note: the gRPC framework executes interceptors within the gRPC handler. If the passed in "ArtifactServiceClient" +// doesn't go through the normal gRPC flow (creating a gRPC client etc.) then it will be up to the passed in +// "ArtifactServiceClient" to call the correct interceptors. +func RegisterArtifactServiceHandlerClient(ctx context.Context, mux *runtime.ServeMux, client ArtifactServiceClient) error { + + mux.Handle("POST", pattern_ArtifactService_Load_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ArtifactService_Load_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArtifactService_Load_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ArtifactService_OpenStream_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ArtifactService_OpenStream_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArtifactService_OpenStream_0(ctx, mux, outboundMarshaler, w, req, func() (proto.Message, error) { return resp.Recv() }, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ArtifactService_Save_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ArtifactService_Save_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArtifactService_Save_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ArtifactService_Delete_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ArtifactService_Delete_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArtifactService_Delete_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ArtifactService_ListObjects_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ArtifactService_ListObjects_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArtifactService_ListObjects_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + mux.Handle("POST", pattern_ArtifactService_IsDirectory_0, func(w http.ResponseWriter, req *http.Request, pathParams map[string]string) { + ctx, cancel := context.WithCancel(req.Context()) + defer cancel() + inboundMarshaler, outboundMarshaler := runtime.MarshalerForRequest(mux, req) + rctx, err := runtime.AnnotateContext(ctx, mux, req) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + resp, md, err := request_ArtifactService_IsDirectory_0(rctx, inboundMarshaler, client, req, pathParams) + ctx = runtime.NewServerMetadataContext(ctx, md) + if err != nil { + runtime.HTTPError(ctx, mux, outboundMarshaler, w, req, err) + return + } + + forward_ArtifactService_IsDirectory_0(ctx, mux, outboundMarshaler, w, req, resp, mux.GetForwardResponseOptions()...) + + }) + + return nil +} + +var ( + pattern_ArtifactService_Load_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "artifacts", "load"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_ArtifactService_OpenStream_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "artifacts", "stream"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_ArtifactService_Save_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "artifacts", "save"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_ArtifactService_Delete_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "artifacts", "delete"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_ArtifactService_ListObjects_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "artifacts", "list"}, "", runtime.AssumeColonVerbOpt(true))) + + pattern_ArtifactService_IsDirectory_0 = runtime.MustPattern(runtime.NewPattern(1, []int{2, 0, 2, 1, 2, 2, 2, 3}, []string{"api", "v1", "artifacts", "is-directory"}, "", runtime.AssumeColonVerbOpt(true))) +) + +var ( + forward_ArtifactService_Load_0 = runtime.ForwardResponseMessage + + forward_ArtifactService_OpenStream_0 = runtime.ForwardResponseStream + + forward_ArtifactService_Save_0 = runtime.ForwardResponseMessage + + forward_ArtifactService_Delete_0 = runtime.ForwardResponseMessage + + forward_ArtifactService_ListObjects_0 = runtime.ForwardResponseMessage + + forward_ArtifactService_IsDirectory_0 = runtime.ForwardResponseMessage +) diff --git a/pkg/apiclient/artifact/artifact.proto b/pkg/apiclient/artifact/artifact.proto new file mode 100644 index 000000000000..fb6518946fdd --- /dev/null +++ b/pkg/apiclient/artifact/artifact.proto @@ -0,0 +1,132 @@ +syntax = "proto3"; +option go_package = "github.com/argoproj/argo-workflows/pkg/apiclient/artifact"; + +import "google/api/annotations.proto"; + +// Artifact Service +// +// Artifact Service API provides GRPC access to artifact operations +package artifact; + +// Plugin Artifact configuration +message PluginArtifact { + string name = 1; + string configuration = 2; + int32 connection_timeout_seconds = 3; + string key = 4; +} + +// Artifact representation for gRPC +message Artifact { + string name = 1; + string path = 2; + int32 mode = 3; + string from = 4; + PluginArtifact plugin = 5; + bool optional = 6; + string sub_path = 7; + bool recurse_mode = 8; + string from_expression = 9; + bool deleted = 10; +} + +message LoadArtifactRequest { + Artifact input_artifact = 1; + string path = 2; +} + +message LoadArtifactResponse { + bool success = 1; + string error = 2; +} + +message OpenStreamRequest { + Artifact artifact = 1; +} + +message OpenStreamResponse { + bytes data = 1; + bool is_end = 2; + string error = 3; +} + +message SaveArtifactRequest { + string path = 1; + Artifact output_artifact = 2; +} + +message SaveArtifactResponse { + bool success = 1; + string error = 2; +} + +message DeleteArtifactRequest { + Artifact artifact = 1; +} + +message DeleteArtifactResponse { + bool success = 1; + string error = 2; +} + +message ListObjectsRequest { + Artifact artifact = 1; +} + +message ListObjectsResponse { + repeated string objects = 1; + string error = 2; +} + +message IsDirectoryRequest { + Artifact artifact = 1; +} + +message IsDirectoryResponse { + bool is_directory = 1; + string error = 2; +} + +service ArtifactService { + rpc Load(LoadArtifactRequest) returns (LoadArtifactResponse) { + option (google.api.http) = { + post : "/api/v1/artifacts/load" + body : "*" + }; + } + + rpc OpenStream(OpenStreamRequest) returns (stream OpenStreamResponse) { + option (google.api.http) = { + post : "/api/v1/artifacts/stream" + body : "*" + }; + } + + rpc Save(SaveArtifactRequest) returns (SaveArtifactResponse) { + option (google.api.http) = { + post : "/api/v1/artifacts/save" + body : "*" + }; + } + + rpc Delete(DeleteArtifactRequest) returns (DeleteArtifactResponse) { + option (google.api.http) = { + post : "/api/v1/artifacts/delete" + body : "*" + }; + } + + rpc ListObjects(ListObjectsRequest) returns (ListObjectsResponse) { + option (google.api.http) = { + post : "/api/v1/artifacts/list" + body : "*" + }; + } + + rpc IsDirectory(IsDirectoryRequest) returns (IsDirectoryResponse) { + option (google.api.http) = { + post : "/api/v1/artifacts/is-directory" + body : "*" + }; + } +} \ No newline at end of file diff --git a/pkg/apiclient/artifact/artifact.swagger.json b/pkg/apiclient/artifact/artifact.swagger.json new file mode 100644 index 000000000000..60b660a14f7b --- /dev/null +++ b/pkg/apiclient/artifact/artifact.swagger.json @@ -0,0 +1,460 @@ +{ + "swagger": "2.0", + "info": { + "title": "Artifact Service", + "description": "Artifact Service API provides GRPC access to artifact operations", + "version": "version not set" + }, + "consumes": [ + "application/json" + ], + "produces": [ + "application/json" + ], + "paths": { + "/api/v1/artifacts/delete": { + "post": { + "operationId": "ArtifactService_Delete", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/artifact.DeleteArtifactResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/grpc.gateway.runtime.Error" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/artifact.DeleteArtifactRequest" + } + } + ], + "tags": [ + "ArtifactService" + ] + } + }, + "/api/v1/artifacts/is-directory": { + "post": { + "operationId": "ArtifactService_IsDirectory", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/artifact.IsDirectoryResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/grpc.gateway.runtime.Error" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/artifact.IsDirectoryRequest" + } + } + ], + "tags": [ + "ArtifactService" + ] + } + }, + "/api/v1/artifacts/list": { + "post": { + "operationId": "ArtifactService_ListObjects", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/artifact.ListObjectsResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/grpc.gateway.runtime.Error" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/artifact.ListObjectsRequest" + } + } + ], + "tags": [ + "ArtifactService" + ] + } + }, + "/api/v1/artifacts/load": { + "post": { + "operationId": "ArtifactService_Load", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/artifact.LoadArtifactResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/grpc.gateway.runtime.Error" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/artifact.LoadArtifactRequest" + } + } + ], + "tags": [ + "ArtifactService" + ] + } + }, + "/api/v1/artifacts/save": { + "post": { + "operationId": "ArtifactService_Save", + "responses": { + "200": { + "description": "A successful response.", + "schema": { + "$ref": "#/definitions/artifact.SaveArtifactResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/grpc.gateway.runtime.Error" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/artifact.SaveArtifactRequest" + } + } + ], + "tags": [ + "ArtifactService" + ] + } + }, + "/api/v1/artifacts/stream": { + "post": { + "operationId": "ArtifactService_OpenStream", + "responses": { + "200": { + "description": "A successful response.(streaming responses)", + "schema": { + "type": "object", + "properties": { + "result": { + "$ref": "#/definitions/artifact.OpenStreamResponse" + }, + "error": { + "$ref": "#/definitions/grpc.gateway.runtime.StreamError" + } + }, + "title": "Stream result of artifact.OpenStreamResponse" + } + }, + "default": { + "description": "An unexpected error response.", + "schema": { + "$ref": "#/definitions/grpc.gateway.runtime.Error" + } + } + }, + "parameters": [ + { + "name": "body", + "in": "body", + "required": true, + "schema": { + "$ref": "#/definitions/artifact.OpenStreamRequest" + } + } + ], + "tags": [ + "ArtifactService" + ] + } + } + }, + "definitions": { + "artifact.Artifact": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "path": { + "type": "string" + }, + "mode": { + "type": "integer", + "format": "int32" + }, + "from": { + "type": "string" + }, + "plugin": { + "$ref": "#/definitions/artifact.PluginArtifact" + }, + "optional": { + "type": "boolean" + }, + "sub_path": { + "type": "string" + }, + "recurse_mode": { + "type": "boolean" + }, + "from_expression": { + "type": "string" + }, + "deleted": { + "type": "boolean" + } + }, + "title": "Artifact representation for gRPC" + }, + "artifact.DeleteArtifactRequest": { + "type": "object", + "properties": { + "artifact": { + "$ref": "#/definitions/artifact.Artifact" + } + } + }, + "artifact.DeleteArtifactResponse": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + }, + "error": { + "type": "string" + } + } + }, + "artifact.IsDirectoryRequest": { + "type": "object", + "properties": { + "artifact": { + "$ref": "#/definitions/artifact.Artifact" + } + } + }, + "artifact.IsDirectoryResponse": { + "type": "object", + "properties": { + "is_directory": { + "type": "boolean" + }, + "error": { + "type": "string" + } + } + }, + "artifact.ListObjectsRequest": { + "type": "object", + "properties": { + "artifact": { + "$ref": "#/definitions/artifact.Artifact" + } + } + }, + "artifact.ListObjectsResponse": { + "type": "object", + "properties": { + "objects": { + "type": "array", + "items": { + "type": "string" + } + }, + "error": { + "type": "string" + } + } + }, + "artifact.LoadArtifactRequest": { + "type": "object", + "properties": { + "input_artifact": { + "$ref": "#/definitions/artifact.Artifact" + }, + "path": { + "type": "string" + } + } + }, + "artifact.LoadArtifactResponse": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + }, + "error": { + "type": "string" + } + } + }, + "artifact.OpenStreamRequest": { + "type": "object", + "properties": { + "artifact": { + "$ref": "#/definitions/artifact.Artifact" + } + } + }, + "artifact.OpenStreamResponse": { + "type": "object", + "properties": { + "data": { + "type": "string", + "format": "byte" + }, + "is_end": { + "type": "boolean" + }, + "error": { + "type": "string" + } + } + }, + "artifact.PluginArtifact": { + "type": "object", + "properties": { + "name": { + "type": "string" + }, + "configuration": { + "type": "string" + }, + "connection_timeout_seconds": { + "type": "integer", + "format": "int32" + }, + "key": { + "type": "string" + } + }, + "title": "Plugin Artifact configuration" + }, + "artifact.SaveArtifactRequest": { + "type": "object", + "properties": { + "path": { + "type": "string" + }, + "output_artifact": { + "$ref": "#/definitions/artifact.Artifact" + } + } + }, + "artifact.SaveArtifactResponse": { + "type": "object", + "properties": { + "success": { + "type": "boolean" + }, + "error": { + "type": "string" + } + } + }, + "google.protobuf.Any": { + "type": "object", + "properties": { + "type_url": { + "type": "string" + }, + "value": { + "type": "string", + "format": "byte" + } + } + }, + "grpc.gateway.runtime.Error": { + "type": "object", + "properties": { + "error": { + "type": "string" + }, + "code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/google.protobuf.Any" + } + } + } + }, + "grpc.gateway.runtime.StreamError": { + "type": "object", + "properties": { + "grpc_code": { + "type": "integer", + "format": "int32" + }, + "http_code": { + "type": "integer", + "format": "int32" + }, + "message": { + "type": "string" + }, + "http_status": { + "type": "string" + }, + "details": { + "type": "array", + "items": { + "$ref": "#/definitions/google.protobuf.Any" + } + } + } + } + } +} diff --git a/pkg/apis/workflow/v1alpha1/artifact_plugins_test.go b/pkg/apis/workflow/v1alpha1/artifact_plugins_test.go new file mode 100644 index 000000000000..ac5bfb6efc66 --- /dev/null +++ b/pkg/apis/workflow/v1alpha1/artifact_plugins_test.go @@ -0,0 +1,945 @@ +package v1alpha1 + +import ( + "context" + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + apiv1 "k8s.io/api/core/v1" + "k8s.io/utils/ptr" + + "github.com/argoproj/argo-workflows/v3/util/logging" +) + +func TestArtifactPluginName(t *testing.T) { + pluginName := ArtifactPluginName("my-plugin") + + t.Run("SocketDir", func(t *testing.T) { + expected := "/tmp/artifact-plugins/my-plugin" + assert.Equal(t, expected, pluginName.SocketDir()) + }) + + t.Run("SocketPath", func(t *testing.T) { + expected := "/tmp/artifact-plugins/my-plugin/socket" + assert.Equal(t, expected, pluginName.SocketPath()) + }) + + t.Run("VolumeMount", func(t *testing.T) { + volumeMount := pluginName.VolumeMount() + expected := apiv1.VolumeMount{ + Name: "artifact-plugin-my-plugin", + MountPath: "/tmp/artifact-plugins/my-plugin", + } + assert.Equal(t, expected, volumeMount) + }) + + t.Run("Volume", func(t *testing.T) { + volume := pluginName.Volume() + expected := apiv1.Volume{ + Name: "artifact-plugin-my-plugin", + VolumeSource: apiv1.VolumeSource{ + EmptyDir: &apiv1.EmptyDirVolumeSource{}, + }, + } + assert.Equal(t, expected, volume) + }) + + t.Run("PluginNameWithSpecialChars", func(t *testing.T) { + specialPlugin := ArtifactPluginName("my-plugin-v1.2.3") + assert.Equal(t, "/tmp/artifact-plugins/my-plugin-v1.2.3", specialPlugin.SocketDir()) + assert.Equal(t, "artifact-plugin-my-plugin-v1.2.3", specialPlugin.Volume().Name) + }) +} + +func TestPluginArtifact(t *testing.T) { + t.Run("HasLocation_Complete", func(t *testing.T) { + plugin := &PluginArtifact{ + Name: "test-plugin", + Configuration: `{"bucket": "my-bucket"}`, + Key: "path/to/artifact", + } + assert.True(t, plugin.HasLocation()) + }) + + t.Run("HasLocation_MissingName", func(t *testing.T) { + plugin := &PluginArtifact{ + Name: "", + Configuration: `{"bucket": "my-bucket"}`, + Key: "path/to/artifact", + } + assert.False(t, plugin.HasLocation()) + }) + + t.Run("HasLocation_MissingConfiguration", func(t *testing.T) { + plugin := &PluginArtifact{ + Name: "test-plugin", + Configuration: "", + Key: "path/to/artifact", + } + assert.False(t, plugin.HasLocation()) + }) + + t.Run("HasLocation_MissingKey", func(t *testing.T) { + plugin := &PluginArtifact{ + Name: "test-plugin", + Configuration: `{"bucket": "my-bucket"}`, + Key: "", + } + assert.False(t, plugin.HasLocation()) + }) + + t.Run("HasLocation_Nil", func(t *testing.T) { + var plugin *PluginArtifact + assert.False(t, plugin.HasLocation()) + }) + + t.Run("ConnectionTimeoutSeconds", func(t *testing.T) { + plugin := &PluginArtifact{ + Name: "test-plugin", + Configuration: `{"bucket": "my-bucket"}`, + Key: "path/to/artifact", + ConnectionTimeoutSeconds: 30, + } + assert.Equal(t, int32(30), plugin.ConnectionTimeoutSeconds) + assert.True(t, plugin.HasLocation()) + }) +} + +func TestPluginArtifactRepository(t *testing.T) { + t.Run("IntoArtifactLocation_WithKeyFormat", func(t *testing.T) { + repo := &PluginArtifactRepository{ + Name: "my-plugin", + KeyFormat: "custom/{{workflow.name}}/{{pod.name}}/{{artifact.name}}", + Configuration: `{"endpoint": "https://my-storage.com"}`, + } + + location := &ArtifactLocation{} + repo.IntoArtifactLocation(location) + + require.NotNil(t, location.Plugin) + assert.Equal(t, ArtifactPluginName("my-plugin"), location.Plugin.Name) + assert.JSONEq(t, `{"endpoint": "https://my-storage.com"}`, location.Plugin.Configuration) + assert.Equal(t, "custom/{{workflow.name}}/{{pod.name}}/{{artifact.name}}", location.Plugin.Key) + }) + + t.Run("IntoArtifactLocation_WithoutKeyFormat", func(t *testing.T) { + repo := &PluginArtifactRepository{ + Name: "my-plugin", + Configuration: `{"endpoint": "https://my-storage.com"}`, + } + + location := &ArtifactLocation{} + repo.IntoArtifactLocation(location) + + require.NotNil(t, location.Plugin) + assert.Equal(t, ArtifactPluginName("my-plugin"), location.Plugin.Name) + assert.JSONEq(t, `{"endpoint": "https://my-storage.com"}`, location.Plugin.Configuration) + assert.Equal(t, DefaultArchivePattern, location.Plugin.Key) + }) + + t.Run("IntoArtifactLocation_EmptyKeyFormat", func(t *testing.T) { + repo := &PluginArtifactRepository{ + Name: "my-plugin", + KeyFormat: "", + Configuration: `{"endpoint": "https://my-storage.com"}`, + } + + location := &ArtifactLocation{} + repo.IntoArtifactLocation(location) + + require.NotNil(t, location.Plugin) + assert.Equal(t, DefaultArchivePattern, location.Plugin.Key) + }) +} + +func TestArtifactLocation_Plugin(t *testing.T) { + t.Run("HasLocation_Plugin", func(t *testing.T) { + location := &ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "test-plugin", + Configuration: `{"bucket": "my-bucket"}`, + Key: "path/to/artifact", + }, + } + assert.True(t, location.HasLocation()) + }) + + t.Run("HasLocation_PluginIncomplete", func(t *testing.T) { + location := &ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "test-plugin", + Configuration: "", + Key: "path/to/artifact", + }, + } + assert.False(t, location.HasLocation()) + }) +} + +func TestArtifacts_GetPluginNames(t *testing.T) { + ctx := logging.WithLogger(context.Background(), logging.NewTestLogger(logging.Info, logging.JSON)) + + t.Run("NoPlugins", func(t *testing.T) { + artifacts := Artifacts{ + { + Name: "regular-artifact", + ArtifactLocation: ArtifactLocation{ + S3: &S3Artifact{ + S3Bucket: S3Bucket{Bucket: "my-bucket"}, + Key: "path/to/artifact", + }, + }, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, nil, ExcludeLogs, nil) + assert.Empty(t, pluginNames) + }) + + t.Run("SinglePlugin", func(t *testing.T) { + artifacts := Artifacts{ + { + Name: "plugin-artifact", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "my-plugin", + Configuration: `{"bucket": "my-bucket"}`, + Key: "path/to/artifact", + }, + }, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, nil, ExcludeLogs, nil) + assert.Len(t, pluginNames, 1) + assert.Contains(t, pluginNames, ArtifactPluginName("my-plugin")) + }) + + t.Run("MultiplePlugins", func(t *testing.T) { + artifacts := Artifacts{ + { + Name: "plugin-artifact-1", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "plugin-1", + Configuration: `{"bucket": "bucket-1"}`, + Key: "path/to/artifact1", + }, + }, + }, + { + Name: "plugin-artifact-2", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "plugin-2", + Configuration: `{"bucket": "bucket-2"}`, + Key: "path/to/artifact2", + }, + }, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, nil, ExcludeLogs, nil) + assert.Len(t, pluginNames, 2) + assert.Contains(t, pluginNames, ArtifactPluginName("plugin-1")) + assert.Contains(t, pluginNames, ArtifactPluginName("plugin-2")) + }) + + t.Run("DuplicatePlugins", func(t *testing.T) { + artifacts := Artifacts{ + { + Name: "plugin-artifact-1", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "my-plugin", + Configuration: `{"bucket": "bucket-1"}`, + Key: "path/to/artifact1", + }, + }, + }, + { + Name: "plugin-artifact-2", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "my-plugin", + Configuration: `{"bucket": "bucket-2"}`, + Key: "path/to/artifact2", + }, + }, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, nil, ExcludeLogs, nil) + assert.Len(t, pluginNames, 1) + assert.Contains(t, pluginNames, ArtifactPluginName("my-plugin")) + }) + + t.Run("WithDefaultRepo", func(t *testing.T) { + artifacts := Artifacts{ + { + Name: "artifact-without-plugin", + ArtifactLocation: ArtifactLocation{ + // No plugin specified, should use default repo + }, + }, + } + + defaultRepo := &ArtifactRepository{ + Plugin: &PluginArtifactRepository{ + Name: "default-plugin", + Configuration: `{"bucket": "default-bucket"}`, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, defaultRepo, ExcludeLogs, nil) + assert.Len(t, pluginNames, 1) + assert.Contains(t, pluginNames, ArtifactPluginName("default-plugin")) + }) + + t.Run("IncludeLogs", func(t *testing.T) { + artifacts := Artifacts{ + { + Name: "regular-artifact", + ArtifactLocation: ArtifactLocation{ + S3: &S3Artifact{ + S3Bucket: S3Bucket{Bucket: "my-bucket"}, + Key: "path/to/artifact", + }, + }, + }, + } + + defaultRepo := &ArtifactRepository{ + Plugin: &PluginArtifactRepository{ + Name: "log-plugin", + Configuration: `{"bucket": "log-bucket"}`, + }, + ArchiveLogs: ptr.To(true), + } + + pluginNames := artifacts.GetPluginNames(ctx, defaultRepo, IncludeLogs, nil) + assert.Len(t, pluginNames, 1) + assert.Contains(t, pluginNames, ArtifactPluginName("log-plugin")) + }) + + t.Run("ExcludeLogs", func(t *testing.T) { + artifacts := Artifacts{ + { + Name: "regular-artifact", + ArtifactLocation: ArtifactLocation{ + S3: &S3Artifact{ + S3Bucket: S3Bucket{Bucket: "my-bucket"}, + Key: "path/to/artifact", + }, + }, + }, + } + + defaultRepo := &ArtifactRepository{ + S3: &S3ArtifactRepository{ + S3Bucket: S3Bucket{Bucket: "log-bucket"}, + }, + ArchiveLogs: ptr.To(true), + } + + pluginNames := artifacts.GetPluginNames(ctx, defaultRepo, ExcludeLogs, nil) + // When ExcludeLogs is used and there are no plugin artifacts, should be empty + assert.Empty(t, pluginNames) + }) + + t.Run("MixedArtifacts", func(t *testing.T) { + artifacts := Artifacts{ + { + Name: "s3-artifact", + ArtifactLocation: ArtifactLocation{ + S3: &S3Artifact{ + S3Bucket: S3Bucket{Bucket: "s3-bucket"}, + Key: "path/to/s3-artifact", + }, + }, + }, + { + Name: "plugin-artifact", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "my-plugin", + Configuration: `{"bucket": "plugin-bucket"}`, + Key: "path/to/plugin-artifact", + }, + }, + }, + { + Name: "default-artifact", + ArtifactLocation: ArtifactLocation{ + // No specific location, should use default + }, + }, + } + + defaultRepo := &ArtifactRepository{ + Plugin: &PluginArtifactRepository{ + Name: "default-plugin", + Configuration: `{"bucket": "default-bucket"}`, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, defaultRepo, ExcludeLogs, nil) + assert.Len(t, pluginNames, 2) + assert.Contains(t, pluginNames, ArtifactPluginName("my-plugin")) + assert.Contains(t, pluginNames, ArtifactPluginName("default-plugin")) + }) + + t.Run("MultiplePluginsWithDefaultRepo", func(t *testing.T) { + artifacts := Artifacts{ + { + Name: "plugin-artifact-1", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "plugin-1", + Configuration: `{"bucket": "bucket-1"}`, + Key: "path/to/artifact1", + }, + }, + }, + { + Name: "plugin-artifact-2", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "plugin-2", + Configuration: `{"bucket": "bucket-2"}`, + Key: "path/to/artifact2", + }, + }, + }, + { + Name: "default-artifact", + ArtifactLocation: ArtifactLocation{ + // No specific location, should use default repo + }, + }, + } + + defaultRepo := &ArtifactRepository{ + Plugin: &PluginArtifactRepository{ + Name: "default-plugin", + Configuration: `{"bucket": "default-bucket"}`, + }, + ArchiveLogs: ptr.To(true), + } + + pluginNames := artifacts.GetPluginNames(ctx, defaultRepo, IncludeLogs, nil) + assert.Len(t, pluginNames, 3) + assert.Contains(t, pluginNames, ArtifactPluginName("plugin-1")) + assert.Contains(t, pluginNames, ArtifactPluginName("plugin-2")) + assert.Contains(t, pluginNames, ArtifactPluginName("default-plugin")) + }) + + t.Run("MultiplePluginsWithLogging", func(t *testing.T) { + artifacts := Artifacts{ + { + Name: "s3-artifact", + ArtifactLocation: ArtifactLocation{ + S3: &S3Artifact{ + S3Bucket: S3Bucket{Bucket: "s3-bucket"}, + Key: "path/to/s3-artifact", + }, + }, + }, + { + Name: "plugin-artifact-1", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "storage-plugin", + Configuration: `{"endpoint": "https://storage1.com"}`, + Key: "path/to/plugin-artifact1", + }, + }, + }, + { + Name: "plugin-artifact-2", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "backup-plugin", + Configuration: `{"endpoint": "https://backup.com"}`, + Key: "path/to/plugin-artifact2", + }, + }, + }, + } + + defaultRepo := &ArtifactRepository{ + Plugin: &PluginArtifactRepository{ + Name: "log-plugin", + Configuration: `{"endpoint": "https://logs.com"}`, + }, + ArchiveLogs: ptr.To(true), + } + + pluginNames := artifacts.GetPluginNames(ctx, defaultRepo, IncludeLogs, nil) + assert.Len(t, pluginNames, 3) + assert.Contains(t, pluginNames, ArtifactPluginName("storage-plugin")) + assert.Contains(t, pluginNames, ArtifactPluginName("backup-plugin")) + assert.Contains(t, pluginNames, ArtifactPluginName("log-plugin")) + }) + + t.Run("SamePluginMultipleConfigurations", func(t *testing.T) { + artifacts := Artifacts{ + { + Name: "plugin-artifact-1", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "my-plugin", + Configuration: `{"bucket": "bucket-1", "region": "us-east-1"}`, + Key: "path/to/artifact1", + }, + }, + }, + { + Name: "plugin-artifact-2", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "my-plugin", + Configuration: `{"bucket": "bucket-2", "region": "us-west-2"}`, + Key: "path/to/artifact2", + }, + }, + }, + { + Name: "plugin-artifact-3", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "other-plugin", + Configuration: `{"endpoint": "https://other.com"}`, + Key: "path/to/artifact3", + }, + }, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, nil, ExcludeLogs, nil) + // Should only have 2 unique plugin names despite 3 artifacts + assert.Len(t, pluginNames, 2) + assert.Contains(t, pluginNames, ArtifactPluginName("my-plugin")) + assert.Contains(t, pluginNames, ArtifactPluginName("other-plugin")) + }) + + t.Run("ComplexMultiPluginScenario", func(t *testing.T) { + artifacts := Artifacts{ + { + Name: "input-artifact", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "input-plugin", + Configuration: `{"source": "external"}`, + Key: "inputs/data.json", + }, + }, + }, + { + Name: "processing-artifact", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "processing-plugin", + Configuration: `{"temp": true}`, + Key: "temp/processing.dat", + }, + }, + }, + { + Name: "output-artifact", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "output-plugin", + Configuration: `{"destination": "final"}`, + Key: "outputs/result.json", + }, + }, + }, + { + Name: "backup-artifact", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "backup-plugin", + Configuration: `{"retention": "30d"}`, + Key: "backups/result-backup.json", + }, + }, + }, + { + Name: "s3-artifact", + ArtifactLocation: ArtifactLocation{ + S3: &S3Artifact{ + S3Bucket: S3Bucket{Bucket: "legacy-bucket"}, + Key: "legacy/data.json", + }, + }, + }, + { + Name: "default-artifact", + ArtifactLocation: ArtifactLocation{ + // Uses default repo + }, + }, + } + + defaultRepo := &ArtifactRepository{ + Plugin: &PluginArtifactRepository{ + Name: "default-plugin", + Configuration: `{"default": true}`, + }, + ArchiveLogs: ptr.To(true), + } + + pluginNames := artifacts.GetPluginNames(ctx, defaultRepo, IncludeLogs, nil) + // Should have 5 unique plugins: input, processing, output, backup, default (for both default artifact and logs) + assert.Len(t, pluginNames, 5) + assert.Contains(t, pluginNames, ArtifactPluginName("input-plugin")) + assert.Contains(t, pluginNames, ArtifactPluginName("processing-plugin")) + assert.Contains(t, pluginNames, ArtifactPluginName("output-plugin")) + assert.Contains(t, pluginNames, ArtifactPluginName("backup-plugin")) + assert.Contains(t, pluginNames, ArtifactPluginName("default-plugin")) + }) + + t.Run("ArchiveLocation", func(t *testing.T) { + t.Run("WithPlugin", func(t *testing.T) { + // Test that archiveLocation plugin is used when artifact doesn't have explicit plugin + artifacts := Artifacts{ + { + Name: "artifact-without-plugin", + ArtifactLocation: ArtifactLocation{ + // No plugin specified, should use archiveLocation + }, + }, + } + + archiveLocation := &ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "archive-plugin", + Configuration: `{"bucket": "archive-bucket"}`, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, nil, ExcludeLogs, archiveLocation) + assert.Len(t, pluginNames, 1) + assert.Contains(t, pluginNames, ArtifactPluginName("archive-plugin")) + }) + + t.Run("PluginNotUsedWhenArtifactHasPlugin", func(t *testing.T) { + // Test that artifact's explicit plugin takes priority over archiveLocation + artifacts := Artifacts{ + { + Name: "artifact-with-plugin", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "artifact-plugin", + Configuration: `{"bucket": "artifact-bucket"}`, + Key: "path/to/artifact", + }, + }, + }, + } + + archiveLocation := &ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "archive-plugin", + Configuration: `{"bucket": "archive-bucket"}`, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, nil, ExcludeLogs, archiveLocation) + assert.Len(t, pluginNames, 1) + assert.Contains(t, pluginNames, ArtifactPluginName("artifact-plugin")) + assert.NotContains(t, pluginNames, ArtifactPluginName("archive-plugin")) + }) + + t.Run("PriorityOverDefaultRepo", func(t *testing.T) { + // Test that archiveLocation takes priority over defaultRepo + artifacts := Artifacts{ + { + Name: "artifact-without-plugin", + ArtifactLocation: ArtifactLocation{ + // No plugin specified + }, + }, + } + + defaultRepo := &ArtifactRepository{ + Plugin: &PluginArtifactRepository{ + Name: "default-plugin", + Configuration: `{"bucket": "default-bucket"}`, + }, + } + + archiveLocation := &ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "archive-plugin", + Configuration: `{"bucket": "archive-bucket"}`, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, defaultRepo, ExcludeLogs, archiveLocation) + assert.Len(t, pluginNames, 1) + assert.Contains(t, pluginNames, ArtifactPluginName("archive-plugin")) + assert.NotContains(t, pluginNames, ArtifactPluginName("default-plugin")) + }) + + t.Run("WithMultipleArtifacts", func(t *testing.T) { + // Test archiveLocation with mix of artifacts with and without explicit plugins + artifacts := Artifacts{ + { + Name: "artifact-with-plugin", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "specific-plugin", + Configuration: `{"bucket": "specific-bucket"}`, + Key: "path/to/artifact1", + }, + }, + }, + { + Name: "artifact-without-plugin-1", + ArtifactLocation: ArtifactLocation{ + // Should use archiveLocation + }, + }, + { + Name: "artifact-without-plugin-2", + ArtifactLocation: ArtifactLocation{ + // Should use archiveLocation + }, + }, + } + + archiveLocation := &ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "archive-plugin", + Configuration: `{"bucket": "archive-bucket"}`, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, nil, ExcludeLogs, archiveLocation) + assert.Len(t, pluginNames, 2) + assert.Contains(t, pluginNames, ArtifactPluginName("specific-plugin")) + assert.Contains(t, pluginNames, ArtifactPluginName("archive-plugin")) + }) + + t.Run("NilDoesNotCrash", func(t *testing.T) { + // Test that nil archiveLocation doesn't cause issues + artifacts := Artifacts{ + { + Name: "artifact-without-plugin", + ArtifactLocation: ArtifactLocation{}, + }, + } + + defaultRepo := &ArtifactRepository{ + Plugin: &PluginArtifactRepository{ + Name: "default-plugin", + Configuration: `{"bucket": "default-bucket"}`, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, defaultRepo, ExcludeLogs, nil) + assert.Len(t, pluginNames, 1) + assert.Contains(t, pluginNames, ArtifactPluginName("default-plugin")) + }) + + t.Run("WithS3FallsBackToDefault", func(t *testing.T) { + // Test that archiveLocation with S3 (not plugin) falls back to defaultRepo for plugin + artifacts := Artifacts{ + { + Name: "artifact-without-plugin", + ArtifactLocation: ArtifactLocation{}, + }, + } + + defaultRepo := &ArtifactRepository{ + Plugin: &PluginArtifactRepository{ + Name: "default-plugin", + Configuration: `{"bucket": "default-bucket"}`, + }, + } + + archiveLocation := &ArtifactLocation{ + S3: &S3Artifact{ + S3Bucket: S3Bucket{Bucket: "s3-bucket"}, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, defaultRepo, ExcludeLogs, archiveLocation) + assert.Len(t, pluginNames, 1) + assert.Contains(t, pluginNames, ArtifactPluginName("default-plugin")) + }) + + t.Run("WithPluginAndLogging", func(t *testing.T) { + // Test archiveLocation plugin with logging enabled + artifacts := Artifacts{ + { + Name: "artifact-without-plugin", + ArtifactLocation: ArtifactLocation{}, + }, + } + + defaultRepo := &ArtifactRepository{ + Plugin: &PluginArtifactRepository{ + Name: "log-plugin", + Configuration: `{"bucket": "log-bucket"}`, + }, + ArchiveLogs: ptr.To(true), + } + + archiveLocation := &ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "archive-plugin", + Configuration: `{"bucket": "archive-bucket"}`, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, defaultRepo, IncludeLogs, archiveLocation) + // Should have both: archive-plugin for artifacts and log-plugin for logging + assert.Len(t, pluginNames, 2) + assert.Contains(t, pluginNames, ArtifactPluginName("archive-plugin")) + assert.Contains(t, pluginNames, ArtifactPluginName("log-plugin")) + }) + + t.Run("EmptyPluginFallsBackToDefault", func(t *testing.T) { + // Test that archiveLocation with empty plugin configuration falls back to defaultRepo + artifacts := Artifacts{ + { + Name: "artifact-without-plugin", + ArtifactLocation: ArtifactLocation{}, + }, + } + + defaultRepo := &ArtifactRepository{ + Plugin: &PluginArtifactRepository{ + Name: "default-plugin", + Configuration: `{"bucket": "default-bucket"}`, + }, + } + + archiveLocation := &ArtifactLocation{ + Plugin: &PluginArtifact{ + // Empty name should not be used + Name: "", + Configuration: "", + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, defaultRepo, ExcludeLogs, archiveLocation) + assert.Len(t, pluginNames, 1) + assert.Contains(t, pluginNames, ArtifactPluginName("default-plugin")) + }) + + t.Run("WithDifferentPluginsThanArtifacts", func(t *testing.T) { + // Test complex scenario with multiple different plugin sources + artifacts := Artifacts{ + { + Name: "explicit-plugin-artifact", + ArtifactLocation: ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "explicit-plugin", + Configuration: `{"bucket": "explicit-bucket"}`, + Key: "path/to/artifact", + }, + }, + }, + { + Name: "archive-location-artifact", + ArtifactLocation: ArtifactLocation{ + // Should use archiveLocation + }, + }, + } + + defaultRepo := &ArtifactRepository{ + Plugin: &PluginArtifactRepository{ + Name: "default-plugin", + Configuration: `{"bucket": "default-bucket"}`, + }, + } + + archiveLocation := &ArtifactLocation{ + Plugin: &PluginArtifact{ + Name: "archive-plugin", + Configuration: `{"bucket": "archive-bucket"}`, + }, + } + + pluginNames := artifacts.GetPluginNames(ctx, defaultRepo, ExcludeLogs, archiveLocation) + assert.Len(t, pluginNames, 2) + assert.Contains(t, pluginNames, ArtifactPluginName("explicit-plugin")) + assert.Contains(t, pluginNames, ArtifactPluginName("archive-plugin")) + // Default plugin should not be included since archiveLocation has priority + assert.NotContains(t, pluginNames, ArtifactPluginName("default-plugin")) + }) + }) +} + +func TestMultiplePluginArtifactRepositories(t *testing.T) { + t.Run("DifferentPluginRepositories", func(t *testing.T) { + repo1 := &PluginArtifactRepository{ + Name: "plugin-1", + KeyFormat: "repo1/{{workflow.name}}/{{pod.name}}", + Configuration: `{"endpoint": "https://repo1.com"}`, + } + + repo2 := &PluginArtifactRepository{ + Name: "plugin-2", + KeyFormat: "repo2/{{workflow.name}}/{{pod.name}}", + Configuration: `{"endpoint": "https://repo2.com"}`, + } + + location1 := &ArtifactLocation{} + repo1.IntoArtifactLocation(location1) + + location2 := &ArtifactLocation{} + repo2.IntoArtifactLocation(location2) + + // Verify both locations are configured correctly + require.NotNil(t, location1.Plugin) + require.NotNil(t, location2.Plugin) + + assert.Equal(t, ArtifactPluginName("plugin-1"), location1.Plugin.Name) + assert.Equal(t, "repo1/{{workflow.name}}/{{pod.name}}", location1.Plugin.Key) + assert.JSONEq(t, `{"endpoint": "https://repo1.com"}`, location1.Plugin.Configuration) + + assert.Equal(t, ArtifactPluginName("plugin-2"), location2.Plugin.Name) + assert.Equal(t, "repo2/{{workflow.name}}/{{pod.name}}", location2.Plugin.Key) + assert.JSONEq(t, `{"endpoint": "https://repo2.com"}`, location2.Plugin.Configuration) + }) + + t.Run("SamePluginDifferentConfigurations", func(t *testing.T) { + repo1 := &PluginArtifactRepository{ + Name: "shared-plugin", + KeyFormat: "env1/{{workflow.name}}/{{pod.name}}", + Configuration: `{"environment": "production", "region": "us-east-1"}`, + } + + repo2 := &PluginArtifactRepository{ + Name: "shared-plugin", + KeyFormat: "env2/{{workflow.name}}/{{pod.name}}", + Configuration: `{"environment": "staging", "region": "us-west-2"}`, + } + + location1 := &ArtifactLocation{} + repo1.IntoArtifactLocation(location1) + + location2 := &ArtifactLocation{} + repo2.IntoArtifactLocation(location2) + + // Both should use the same plugin name but different configurations + require.NotNil(t, location1.Plugin) + require.NotNil(t, location2.Plugin) + + assert.Equal(t, ArtifactPluginName("shared-plugin"), location1.Plugin.Name) + assert.Equal(t, ArtifactPluginName("shared-plugin"), location2.Plugin.Name) + + assert.Equal(t, "env1/{{workflow.name}}/{{pod.name}}", location1.Plugin.Key) + assert.Equal(t, "env2/{{workflow.name}}/{{pod.name}}", location2.Plugin.Key) + + assert.JSONEq(t, `{"environment": "production", "region": "us-east-1"}`, location1.Plugin.Configuration) + assert.JSONEq(t, `{"environment": "staging", "region": "us-west-2"}`, location2.Plugin.Configuration) + }) +} diff --git a/pkg/apis/workflow/v1alpha1/artifact_repository_types.go b/pkg/apis/workflow/v1alpha1/artifact_repository_types.go index 8c2ae9945b24..66a5ec77ce6d 100644 --- a/pkg/apis/workflow/v1alpha1/artifact_repository_types.go +++ b/pkg/apis/workflow/v1alpha1/artifact_repository_types.go @@ -6,7 +6,7 @@ import ( "strings" ) -var ( +const ( // DefaultArchivePattern is the default pattern when storing artifacts in an archive repository DefaultArchivePattern = "{{workflow.name}}/{{pod.name}}" ) @@ -27,6 +27,8 @@ type ArtifactRepository struct { GCS *GCSArtifactRepository `json:"gcs,omitempty" protobuf:"bytes,6,opt,name=gcs"` // Azure stores artifact in an Azure Storage account Azure *AzureArtifactRepository `json:"azure,omitempty" protobuf:"bytes,7,opt,name=azure"` + // Plugin stores artifact in a plugin-specific artifact repository + Plugin *PluginArtifactRepository `json:"plugin,omitempty" protobuf:"bytes,8,opt,name=plugin"` } func (a *ArtifactRepository) IsArchiveLogs() bool { @@ -50,6 +52,8 @@ func (a *ArtifactRepository) Get() ArtifactRepositoryType { return a.HDFS } else if a.OSS != nil { return a.OSS + } else if a.Plugin != nil { + return a.Plugin } else if a.S3 != nil { return a.S3 } @@ -178,4 +182,17 @@ func (r *HDFSArtifactRepository) IntoArtifactLocation(l *ArtifactLocation) { l.HDFS = &HDFSArtifact{HDFSConfig: r.HDFSConfig, Path: p, Force: r.Force} } -// MetricsConfig defines a config for a metrics server +// PluginArtifactRepository defines the controller configuration for a plugin artifact repository +type PluginArtifactRepository struct { + Name ArtifactPluginName `json:"name" protobuf:"bytes,1,opt,name=name"` + KeyFormat string `json:"keyFormat,omitempty" protobuf:"bytes,2,opt,name=keyFormat"` + Configuration string `json:"configuration" protobuf:"bytes,3,opt,name=configuration"` +} + +func (r *PluginArtifactRepository) IntoArtifactLocation(l *ArtifactLocation) { + k := r.KeyFormat + if k == "" { + k = DefaultArchivePattern + } + l.Plugin = &PluginArtifact{Name: r.Name, Configuration: r.Configuration, Key: k} +} diff --git a/pkg/apis/workflow/v1alpha1/artifact_repository_types_test.go b/pkg/apis/workflow/v1alpha1/artifact_repository_types_test.go index 78067b0138f2..ac1ba8e06ea8 100644 --- a/pkg/apis/workflow/v1alpha1/artifact_repository_types_test.go +++ b/pkg/apis/workflow/v1alpha1/artifact_repository_types_test.go @@ -48,6 +48,13 @@ func TestArtifactRepository(t *testing.T) { require.NotNil(t, l.HDFS) assert.Equal(t, "{{workflow.name}}/{{pod.name}}", l.HDFS.Path) }) + t.Run("Plugin", func(t *testing.T) { + r := &ArtifactRepository{Plugin: &PluginArtifactRepository{}} + assert.IsType(t, &PluginArtifactRepository{}, r.Get()) + l := r.ToArtifactLocation() + require.NotNil(t, l.Plugin) + assert.Equal(t, "{{workflow.name}}/{{pod.name}}", l.Plugin.Key) + }) t.Run("OSS", func(t *testing.T) { r := &ArtifactRepository{OSS: &OSSArtifactRepository{}} assert.IsType(t, &OSSArtifactRepository{}, r.Get()) diff --git a/pkg/apis/workflow/v1alpha1/generated.pb.go b/pkg/apis/workflow/v1alpha1/generated.pb.go index f0561a9123bd..9275d50f068c 100644 --- a/pkg/apis/workflow/v1alpha1/generated.pb.go +++ b/pkg/apis/workflow/v1alpha1/generated.pb.go @@ -2752,10 +2752,66 @@ func (m *Plugin) XXX_DiscardUnknown() { var xxx_messageInfo_Plugin proto.InternalMessageInfo +func (m *PluginArtifact) Reset() { *m = PluginArtifact{} } +func (*PluginArtifact) ProtoMessage() {} +func (*PluginArtifact) Descriptor() ([]byte, []int) { + return fileDescriptor_724696e352c3df5f, []int{97} +} +func (m *PluginArtifact) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PluginArtifact) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PluginArtifact) XXX_Merge(src proto.Message) { + xxx_messageInfo_PluginArtifact.Merge(m, src) +} +func (m *PluginArtifact) XXX_Size() int { + return m.Size() +} +func (m *PluginArtifact) XXX_DiscardUnknown() { + xxx_messageInfo_PluginArtifact.DiscardUnknown(m) +} + +var xxx_messageInfo_PluginArtifact proto.InternalMessageInfo + +func (m *PluginArtifactRepository) Reset() { *m = PluginArtifactRepository{} } +func (*PluginArtifactRepository) ProtoMessage() {} +func (*PluginArtifactRepository) Descriptor() ([]byte, []int) { + return fileDescriptor_724696e352c3df5f, []int{98} +} +func (m *PluginArtifactRepository) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *PluginArtifactRepository) XXX_Marshal(b []byte, deterministic bool) ([]byte, error) { + b = b[:cap(b)] + n, err := m.MarshalToSizedBuffer(b) + if err != nil { + return nil, err + } + return b[:n], nil +} +func (m *PluginArtifactRepository) XXX_Merge(src proto.Message) { + xxx_messageInfo_PluginArtifactRepository.Merge(m, src) +} +func (m *PluginArtifactRepository) XXX_Size() int { + return m.Size() +} +func (m *PluginArtifactRepository) XXX_DiscardUnknown() { + xxx_messageInfo_PluginArtifactRepository.DiscardUnknown(m) +} + +var xxx_messageInfo_PluginArtifactRepository proto.InternalMessageInfo + func (m *PodGC) Reset() { *m = PodGC{} } func (*PodGC) ProtoMessage() {} func (*PodGC) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{97} + return fileDescriptor_724696e352c3df5f, []int{99} } func (m *PodGC) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2783,7 +2839,7 @@ var xxx_messageInfo_PodGC proto.InternalMessageInfo func (m *Prometheus) Reset() { *m = Prometheus{} } func (*Prometheus) ProtoMessage() {} func (*Prometheus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{98} + return fileDescriptor_724696e352c3df5f, []int{100} } func (m *Prometheus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2811,7 +2867,7 @@ var xxx_messageInfo_Prometheus proto.InternalMessageInfo func (m *RawArtifact) Reset() { *m = RawArtifact{} } func (*RawArtifact) ProtoMessage() {} func (*RawArtifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{99} + return fileDescriptor_724696e352c3df5f, []int{101} } func (m *RawArtifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2839,7 +2895,7 @@ var xxx_messageInfo_RawArtifact proto.InternalMessageInfo func (m *ResourceTemplate) Reset() { *m = ResourceTemplate{} } func (*ResourceTemplate) ProtoMessage() {} func (*ResourceTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{100} + return fileDescriptor_724696e352c3df5f, []int{102} } func (m *ResourceTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2867,7 +2923,7 @@ var xxx_messageInfo_ResourceTemplate proto.InternalMessageInfo func (m *RetryAffinity) Reset() { *m = RetryAffinity{} } func (*RetryAffinity) ProtoMessage() {} func (*RetryAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{101} + return fileDescriptor_724696e352c3df5f, []int{103} } func (m *RetryAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2895,7 +2951,7 @@ var xxx_messageInfo_RetryAffinity proto.InternalMessageInfo func (m *RetryNodeAntiAffinity) Reset() { *m = RetryNodeAntiAffinity{} } func (*RetryNodeAntiAffinity) ProtoMessage() {} func (*RetryNodeAntiAffinity) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{102} + return fileDescriptor_724696e352c3df5f, []int{104} } func (m *RetryNodeAntiAffinity) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2923,7 +2979,7 @@ var xxx_messageInfo_RetryNodeAntiAffinity proto.InternalMessageInfo func (m *RetryStrategy) Reset() { *m = RetryStrategy{} } func (*RetryStrategy) ProtoMessage() {} func (*RetryStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{103} + return fileDescriptor_724696e352c3df5f, []int{105} } func (m *RetryStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2951,7 +3007,7 @@ var xxx_messageInfo_RetryStrategy proto.InternalMessageInfo func (m *S3Artifact) Reset() { *m = S3Artifact{} } func (*S3Artifact) ProtoMessage() {} func (*S3Artifact) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{104} + return fileDescriptor_724696e352c3df5f, []int{106} } func (m *S3Artifact) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2979,7 +3035,7 @@ var xxx_messageInfo_S3Artifact proto.InternalMessageInfo func (m *S3ArtifactRepository) Reset() { *m = S3ArtifactRepository{} } func (*S3ArtifactRepository) ProtoMessage() {} func (*S3ArtifactRepository) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{105} + return fileDescriptor_724696e352c3df5f, []int{107} } func (m *S3ArtifactRepository) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3007,7 +3063,7 @@ var xxx_messageInfo_S3ArtifactRepository proto.InternalMessageInfo func (m *S3Bucket) Reset() { *m = S3Bucket{} } func (*S3Bucket) ProtoMessage() {} func (*S3Bucket) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{106} + return fileDescriptor_724696e352c3df5f, []int{108} } func (m *S3Bucket) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3035,7 +3091,7 @@ var xxx_messageInfo_S3Bucket proto.InternalMessageInfo func (m *S3EncryptionOptions) Reset() { *m = S3EncryptionOptions{} } func (*S3EncryptionOptions) ProtoMessage() {} func (*S3EncryptionOptions) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{107} + return fileDescriptor_724696e352c3df5f, []int{109} } func (m *S3EncryptionOptions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3063,7 +3119,7 @@ var xxx_messageInfo_S3EncryptionOptions proto.InternalMessageInfo func (m *ScriptTemplate) Reset() { *m = ScriptTemplate{} } func (*ScriptTemplate) ProtoMessage() {} func (*ScriptTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{108} + return fileDescriptor_724696e352c3df5f, []int{110} } func (m *ScriptTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3091,7 +3147,7 @@ var xxx_messageInfo_ScriptTemplate proto.InternalMessageInfo func (m *SemaphoreHolding) Reset() { *m = SemaphoreHolding{} } func (*SemaphoreHolding) ProtoMessage() {} func (*SemaphoreHolding) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{109} + return fileDescriptor_724696e352c3df5f, []int{111} } func (m *SemaphoreHolding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3119,7 +3175,7 @@ var xxx_messageInfo_SemaphoreHolding proto.InternalMessageInfo func (m *SemaphoreRef) Reset() { *m = SemaphoreRef{} } func (*SemaphoreRef) ProtoMessage() {} func (*SemaphoreRef) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{110} + return fileDescriptor_724696e352c3df5f, []int{112} } func (m *SemaphoreRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3147,7 +3203,7 @@ var xxx_messageInfo_SemaphoreRef proto.InternalMessageInfo func (m *SemaphoreStatus) Reset() { *m = SemaphoreStatus{} } func (*SemaphoreStatus) ProtoMessage() {} func (*SemaphoreStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{111} + return fileDescriptor_724696e352c3df5f, []int{113} } func (m *SemaphoreStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3175,7 +3231,7 @@ var xxx_messageInfo_SemaphoreStatus proto.InternalMessageInfo func (m *Sequence) Reset() { *m = Sequence{} } func (*Sequence) ProtoMessage() {} func (*Sequence) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{112} + return fileDescriptor_724696e352c3df5f, []int{114} } func (m *Sequence) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3203,7 +3259,7 @@ var xxx_messageInfo_Sequence proto.InternalMessageInfo func (m *StopStrategy) Reset() { *m = StopStrategy{} } func (*StopStrategy) ProtoMessage() {} func (*StopStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{113} + return fileDescriptor_724696e352c3df5f, []int{115} } func (m *StopStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3231,7 +3287,7 @@ var xxx_messageInfo_StopStrategy proto.InternalMessageInfo func (m *Submit) Reset() { *m = Submit{} } func (*Submit) ProtoMessage() {} func (*Submit) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{114} + return fileDescriptor_724696e352c3df5f, []int{116} } func (m *Submit) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3259,7 +3315,7 @@ var xxx_messageInfo_Submit proto.InternalMessageInfo func (m *SubmitOpts) Reset() { *m = SubmitOpts{} } func (*SubmitOpts) ProtoMessage() {} func (*SubmitOpts) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{115} + return fileDescriptor_724696e352c3df5f, []int{117} } func (m *SubmitOpts) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3287,7 +3343,7 @@ var xxx_messageInfo_SubmitOpts proto.InternalMessageInfo func (m *SuppliedValueFrom) Reset() { *m = SuppliedValueFrom{} } func (*SuppliedValueFrom) ProtoMessage() {} func (*SuppliedValueFrom) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{116} + return fileDescriptor_724696e352c3df5f, []int{118} } func (m *SuppliedValueFrom) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3315,7 +3371,7 @@ var xxx_messageInfo_SuppliedValueFrom proto.InternalMessageInfo func (m *SuspendTemplate) Reset() { *m = SuspendTemplate{} } func (*SuspendTemplate) ProtoMessage() {} func (*SuspendTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{117} + return fileDescriptor_724696e352c3df5f, []int{119} } func (m *SuspendTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3343,7 +3399,7 @@ var xxx_messageInfo_SuspendTemplate proto.InternalMessageInfo func (m *SyncDatabaseRef) Reset() { *m = SyncDatabaseRef{} } func (*SyncDatabaseRef) ProtoMessage() {} func (*SyncDatabaseRef) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{118} + return fileDescriptor_724696e352c3df5f, []int{120} } func (m *SyncDatabaseRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3371,7 +3427,7 @@ var xxx_messageInfo_SyncDatabaseRef proto.InternalMessageInfo func (m *Synchronization) Reset() { *m = Synchronization{} } func (*Synchronization) ProtoMessage() {} func (*Synchronization) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{119} + return fileDescriptor_724696e352c3df5f, []int{121} } func (m *Synchronization) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3399,7 +3455,7 @@ var xxx_messageInfo_Synchronization proto.InternalMessageInfo func (m *SynchronizationStatus) Reset() { *m = SynchronizationStatus{} } func (*SynchronizationStatus) ProtoMessage() {} func (*SynchronizationStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{120} + return fileDescriptor_724696e352c3df5f, []int{122} } func (m *SynchronizationStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3427,7 +3483,7 @@ var xxx_messageInfo_SynchronizationStatus proto.InternalMessageInfo func (m *TTLStrategy) Reset() { *m = TTLStrategy{} } func (*TTLStrategy) ProtoMessage() {} func (*TTLStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{121} + return fileDescriptor_724696e352c3df5f, []int{123} } func (m *TTLStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3455,7 +3511,7 @@ var xxx_messageInfo_TTLStrategy proto.InternalMessageInfo func (m *TarStrategy) Reset() { *m = TarStrategy{} } func (*TarStrategy) ProtoMessage() {} func (*TarStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{122} + return fileDescriptor_724696e352c3df5f, []int{124} } func (m *TarStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3483,7 +3539,7 @@ var xxx_messageInfo_TarStrategy proto.InternalMessageInfo func (m *Template) Reset() { *m = Template{} } func (*Template) ProtoMessage() {} func (*Template) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{123} + return fileDescriptor_724696e352c3df5f, []int{125} } func (m *Template) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3511,7 +3567,7 @@ var xxx_messageInfo_Template proto.InternalMessageInfo func (m *TemplateRef) Reset() { *m = TemplateRef{} } func (*TemplateRef) ProtoMessage() {} func (*TemplateRef) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{124} + return fileDescriptor_724696e352c3df5f, []int{126} } func (m *TemplateRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3539,7 +3595,7 @@ var xxx_messageInfo_TemplateRef proto.InternalMessageInfo func (m *TransformationStep) Reset() { *m = TransformationStep{} } func (*TransformationStep) ProtoMessage() {} func (*TransformationStep) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{125} + return fileDescriptor_724696e352c3df5f, []int{127} } func (m *TransformationStep) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3567,7 +3623,7 @@ var xxx_messageInfo_TransformationStep proto.InternalMessageInfo func (m *UserContainer) Reset() { *m = UserContainer{} } func (*UserContainer) ProtoMessage() {} func (*UserContainer) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{126} + return fileDescriptor_724696e352c3df5f, []int{128} } func (m *UserContainer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3595,7 +3651,7 @@ var xxx_messageInfo_UserContainer proto.InternalMessageInfo func (m *ValueFrom) Reset() { *m = ValueFrom{} } func (*ValueFrom) ProtoMessage() {} func (*ValueFrom) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{127} + return fileDescriptor_724696e352c3df5f, []int{129} } func (m *ValueFrom) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3623,7 +3679,7 @@ var xxx_messageInfo_ValueFrom proto.InternalMessageInfo func (m *Version) Reset() { *m = Version{} } func (*Version) ProtoMessage() {} func (*Version) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{128} + return fileDescriptor_724696e352c3df5f, []int{130} } func (m *Version) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3651,7 +3707,7 @@ var xxx_messageInfo_Version proto.InternalMessageInfo func (m *VolumeClaimGC) Reset() { *m = VolumeClaimGC{} } func (*VolumeClaimGC) ProtoMessage() {} func (*VolumeClaimGC) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{129} + return fileDescriptor_724696e352c3df5f, []int{131} } func (m *VolumeClaimGC) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3679,7 +3735,7 @@ var xxx_messageInfo_VolumeClaimGC proto.InternalMessageInfo func (m *Workflow) Reset() { *m = Workflow{} } func (*Workflow) ProtoMessage() {} func (*Workflow) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{130} + return fileDescriptor_724696e352c3df5f, []int{132} } func (m *Workflow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3707,7 +3763,7 @@ var xxx_messageInfo_Workflow proto.InternalMessageInfo func (m *WorkflowArtifactGCTask) Reset() { *m = WorkflowArtifactGCTask{} } func (*WorkflowArtifactGCTask) ProtoMessage() {} func (*WorkflowArtifactGCTask) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{131} + return fileDescriptor_724696e352c3df5f, []int{133} } func (m *WorkflowArtifactGCTask) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3735,7 +3791,7 @@ var xxx_messageInfo_WorkflowArtifactGCTask proto.InternalMessageInfo func (m *WorkflowArtifactGCTaskList) Reset() { *m = WorkflowArtifactGCTaskList{} } func (*WorkflowArtifactGCTaskList) ProtoMessage() {} func (*WorkflowArtifactGCTaskList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{132} + return fileDescriptor_724696e352c3df5f, []int{134} } func (m *WorkflowArtifactGCTaskList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3763,7 +3819,7 @@ var xxx_messageInfo_WorkflowArtifactGCTaskList proto.InternalMessageInfo func (m *WorkflowEventBinding) Reset() { *m = WorkflowEventBinding{} } func (*WorkflowEventBinding) ProtoMessage() {} func (*WorkflowEventBinding) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{133} + return fileDescriptor_724696e352c3df5f, []int{135} } func (m *WorkflowEventBinding) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3791,7 +3847,7 @@ var xxx_messageInfo_WorkflowEventBinding proto.InternalMessageInfo func (m *WorkflowEventBindingList) Reset() { *m = WorkflowEventBindingList{} } func (*WorkflowEventBindingList) ProtoMessage() {} func (*WorkflowEventBindingList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{134} + return fileDescriptor_724696e352c3df5f, []int{136} } func (m *WorkflowEventBindingList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3819,7 +3875,7 @@ var xxx_messageInfo_WorkflowEventBindingList proto.InternalMessageInfo func (m *WorkflowEventBindingSpec) Reset() { *m = WorkflowEventBindingSpec{} } func (*WorkflowEventBindingSpec) ProtoMessage() {} func (*WorkflowEventBindingSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{135} + return fileDescriptor_724696e352c3df5f, []int{137} } func (m *WorkflowEventBindingSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3847,7 +3903,7 @@ var xxx_messageInfo_WorkflowEventBindingSpec proto.InternalMessageInfo func (m *WorkflowLevelArtifactGC) Reset() { *m = WorkflowLevelArtifactGC{} } func (*WorkflowLevelArtifactGC) ProtoMessage() {} func (*WorkflowLevelArtifactGC) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{136} + return fileDescriptor_724696e352c3df5f, []int{138} } func (m *WorkflowLevelArtifactGC) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3875,7 +3931,7 @@ var xxx_messageInfo_WorkflowLevelArtifactGC proto.InternalMessageInfo func (m *WorkflowList) Reset() { *m = WorkflowList{} } func (*WorkflowList) ProtoMessage() {} func (*WorkflowList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{137} + return fileDescriptor_724696e352c3df5f, []int{139} } func (m *WorkflowList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3903,7 +3959,7 @@ var xxx_messageInfo_WorkflowList proto.InternalMessageInfo func (m *WorkflowMetadata) Reset() { *m = WorkflowMetadata{} } func (*WorkflowMetadata) ProtoMessage() {} func (*WorkflowMetadata) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{138} + return fileDescriptor_724696e352c3df5f, []int{140} } func (m *WorkflowMetadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3931,7 +3987,7 @@ var xxx_messageInfo_WorkflowMetadata proto.InternalMessageInfo func (m *WorkflowSpec) Reset() { *m = WorkflowSpec{} } func (*WorkflowSpec) ProtoMessage() {} func (*WorkflowSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{139} + return fileDescriptor_724696e352c3df5f, []int{141} } func (m *WorkflowSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3959,7 +4015,7 @@ var xxx_messageInfo_WorkflowSpec proto.InternalMessageInfo func (m *WorkflowStatus) Reset() { *m = WorkflowStatus{} } func (*WorkflowStatus) ProtoMessage() {} func (*WorkflowStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{140} + return fileDescriptor_724696e352c3df5f, []int{142} } func (m *WorkflowStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -3987,7 +4043,7 @@ var xxx_messageInfo_WorkflowStatus proto.InternalMessageInfo func (m *WorkflowStep) Reset() { *m = WorkflowStep{} } func (*WorkflowStep) ProtoMessage() {} func (*WorkflowStep) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{141} + return fileDescriptor_724696e352c3df5f, []int{143} } func (m *WorkflowStep) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4015,7 +4071,7 @@ var xxx_messageInfo_WorkflowStep proto.InternalMessageInfo func (m *WorkflowTaskResult) Reset() { *m = WorkflowTaskResult{} } func (*WorkflowTaskResult) ProtoMessage() {} func (*WorkflowTaskResult) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{142} + return fileDescriptor_724696e352c3df5f, []int{144} } func (m *WorkflowTaskResult) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4043,7 +4099,7 @@ var xxx_messageInfo_WorkflowTaskResult proto.InternalMessageInfo func (m *WorkflowTaskResultList) Reset() { *m = WorkflowTaskResultList{} } func (*WorkflowTaskResultList) ProtoMessage() {} func (*WorkflowTaskResultList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{143} + return fileDescriptor_724696e352c3df5f, []int{145} } func (m *WorkflowTaskResultList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4071,7 +4127,7 @@ var xxx_messageInfo_WorkflowTaskResultList proto.InternalMessageInfo func (m *WorkflowTaskSet) Reset() { *m = WorkflowTaskSet{} } func (*WorkflowTaskSet) ProtoMessage() {} func (*WorkflowTaskSet) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{144} + return fileDescriptor_724696e352c3df5f, []int{146} } func (m *WorkflowTaskSet) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4099,7 +4155,7 @@ var xxx_messageInfo_WorkflowTaskSet proto.InternalMessageInfo func (m *WorkflowTaskSetList) Reset() { *m = WorkflowTaskSetList{} } func (*WorkflowTaskSetList) ProtoMessage() {} func (*WorkflowTaskSetList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{145} + return fileDescriptor_724696e352c3df5f, []int{147} } func (m *WorkflowTaskSetList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4127,7 +4183,7 @@ var xxx_messageInfo_WorkflowTaskSetList proto.InternalMessageInfo func (m *WorkflowTaskSetSpec) Reset() { *m = WorkflowTaskSetSpec{} } func (*WorkflowTaskSetSpec) ProtoMessage() {} func (*WorkflowTaskSetSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{146} + return fileDescriptor_724696e352c3df5f, []int{148} } func (m *WorkflowTaskSetSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4155,7 +4211,7 @@ var xxx_messageInfo_WorkflowTaskSetSpec proto.InternalMessageInfo func (m *WorkflowTaskSetStatus) Reset() { *m = WorkflowTaskSetStatus{} } func (*WorkflowTaskSetStatus) ProtoMessage() {} func (*WorkflowTaskSetStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{147} + return fileDescriptor_724696e352c3df5f, []int{149} } func (m *WorkflowTaskSetStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4183,7 +4239,7 @@ var xxx_messageInfo_WorkflowTaskSetStatus proto.InternalMessageInfo func (m *WorkflowTemplate) Reset() { *m = WorkflowTemplate{} } func (*WorkflowTemplate) ProtoMessage() {} func (*WorkflowTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{148} + return fileDescriptor_724696e352c3df5f, []int{150} } func (m *WorkflowTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4211,7 +4267,7 @@ var xxx_messageInfo_WorkflowTemplate proto.InternalMessageInfo func (m *WorkflowTemplateList) Reset() { *m = WorkflowTemplateList{} } func (*WorkflowTemplateList) ProtoMessage() {} func (*WorkflowTemplateList) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{149} + return fileDescriptor_724696e352c3df5f, []int{151} } func (m *WorkflowTemplateList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4239,7 +4295,7 @@ var xxx_messageInfo_WorkflowTemplateList proto.InternalMessageInfo func (m *WorkflowTemplateRef) Reset() { *m = WorkflowTemplateRef{} } func (*WorkflowTemplateRef) ProtoMessage() {} func (*WorkflowTemplateRef) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{150} + return fileDescriptor_724696e352c3df5f, []int{152} } func (m *WorkflowTemplateRef) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4267,7 +4323,7 @@ var xxx_messageInfo_WorkflowTemplateRef proto.InternalMessageInfo func (m *ZipStrategy) Reset() { *m = ZipStrategy{} } func (*ZipStrategy) ProtoMessage() {} func (*ZipStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_724696e352c3df5f, []int{151} + return fileDescriptor_724696e352c3df5f, []int{153} } func (m *ZipStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -4402,6 +4458,8 @@ func init() { proto.RegisterType((*ParallelSteps)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.ParallelSteps") proto.RegisterType((*Parameter)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.Parameter") proto.RegisterType((*Plugin)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.Plugin") + proto.RegisterType((*PluginArtifact)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.PluginArtifact") + proto.RegisterType((*PluginArtifactRepository)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.PluginArtifactRepository") proto.RegisterType((*PodGC)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.PodGC") proto.RegisterType((*Prometheus)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.Prometheus") proto.RegisterType((*RawArtifact)(nil), "github.com.argoproj.argo_workflows.v3.pkg.apis.workflow.v1alpha1.RawArtifact") @@ -4478,711 +4536,718 @@ func init() { } var fileDescriptor_724696e352c3df5f = []byte{ - // 11256 bytes of a gzipped FileDescriptorProto + // 11373 bytes of a gzipped FileDescriptorProto 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x7d, 0x6d, 0x70, 0x24, 0xc7, 0x75, 0x18, 0x67, 0x81, 0xc5, 0xc7, 0x5b, 0x00, 0x87, 0xeb, 0xfb, 0x5a, 0x82, 0xe4, 0x81, 0x1e, - 0x8a, 0x0c, 0x69, 0x51, 0x38, 0xf1, 0x28, 0x25, 0x8c, 0x94, 0x48, 0xc2, 0xc7, 0x01, 0x07, 0x02, - 0x38, 0x80, 0xbd, 0x38, 0x9e, 0x49, 0xd1, 0x92, 0x06, 0xbb, 0x8d, 0xdd, 0x21, 0x76, 0x67, 0x96, - 0x33, 0xb3, 0xb8, 0x03, 0x3f, 0x24, 0x85, 0xfa, 0xa2, 0x62, 0xd9, 0x8a, 0x65, 0x4a, 0x96, 0xe4, - 0x24, 0xa5, 0x28, 0x52, 0xa2, 0x92, 0x5d, 0x49, 0xd9, 0xbf, 0x12, 0xfb, 0x5f, 0x7e, 0xb8, 0x94, - 0x72, 0x2a, 0x91, 0x2b, 0x4a, 0x59, 0x3f, 0x62, 0x30, 0x82, 0x13, 0x55, 0x2a, 0x29, 0xfd, 0xb0, - 0x2a, 0x4e, 0xe2, 0xcb, 0x47, 0xb9, 0xfa, 0x73, 0xba, 0x67, 0x67, 0x71, 0x00, 0xae, 0x01, 0xaa, - 0xec, 0x5f, 0xc0, 0xbe, 0x7e, 0xfd, 0x5e, 0x77, 0x4f, 0xf7, 0xeb, 0xd7, 0xef, 0xbd, 0x7e, 0x0d, - 0x6b, 0x75, 0x3f, 0x69, 0x74, 0x36, 0xa6, 0xaa, 0x61, 0xeb, 0x92, 0x17, 0xd5, 0xc3, 0x76, 0x14, - 0xbe, 0xc8, 0xfe, 0x79, 0xd7, 0xcd, 0x30, 0xda, 0xda, 0x6c, 0x86, 0x37, 0xe3, 0x4b, 0xdb, 0x4f, - 0x5e, 0x6a, 0x6f, 0xd5, 0x2f, 0x79, 0x6d, 0x3f, 0xbe, 0x24, 0xa1, 0x97, 0xb6, 0x9f, 0xf0, 0x9a, - 0xed, 0x86, 0xf7, 0xc4, 0xa5, 0x3a, 0x09, 0x48, 0xe4, 0x25, 0xa4, 0x36, 0xd5, 0x8e, 0xc2, 0x24, - 0x44, 0x1f, 0x4a, 0x29, 0x4e, 0x49, 0x8a, 0xec, 0x9f, 0x8f, 0x2a, 0x8a, 0x53, 0xdb, 0x4f, 0x4e, - 0xb5, 0xb7, 0xea, 0x53, 0x94, 0xe2, 0x94, 0x84, 0x4e, 0x49, 0x8a, 0x13, 0xef, 0xd2, 0xda, 0x54, - 0x0f, 0xeb, 0xe1, 0x25, 0x46, 0x78, 0xa3, 0xb3, 0xc9, 0x7e, 0xb1, 0x1f, 0xec, 0x3f, 0xce, 0x70, - 0xc2, 0xdd, 0x7a, 0x2a, 0x9e, 0xf2, 0x43, 0xda, 0xbe, 0x4b, 0xd5, 0x30, 0x22, 0x97, 0xb6, 0xbb, - 0x1a, 0x35, 0xf1, 0x0e, 0x0d, 0xa7, 0x1d, 0x36, 0xfd, 0xea, 0x4e, 0x1e, 0xd6, 0x7b, 0x52, 0xac, - 0x96, 0x57, 0x6d, 0xf8, 0x01, 0x89, 0x76, 0xd2, 0xae, 0xb7, 0x48, 0xe2, 0xe5, 0xd5, 0xba, 0xd4, - 0xab, 0x56, 0xd4, 0x09, 0x12, 0xbf, 0x45, 0xba, 0x2a, 0xfc, 0xf5, 0x3b, 0x55, 0x88, 0xab, 0x0d, - 0xd2, 0xf2, 0xba, 0xea, 0x3d, 0xd9, 0xab, 0x5e, 0x27, 0xf1, 0x9b, 0x97, 0xfc, 0x20, 0x89, 0x93, - 0x28, 0x5b, 0xc9, 0xbd, 0x02, 0x03, 0xd3, 0xad, 0xb0, 0x13, 0x24, 0xe8, 0xfd, 0x50, 0xdc, 0xf6, - 0x9a, 0x1d, 0x52, 0x76, 0x1e, 0x74, 0x1e, 0x1d, 0x9e, 0x79, 0xf8, 0x7b, 0xbb, 0x93, 0xf7, 0xec, - 0xed, 0x4e, 0x16, 0x9f, 0xa5, 0xc0, 0xdb, 0xbb, 0x93, 0x67, 0x49, 0x50, 0x0d, 0x6b, 0x7e, 0x50, - 0xbf, 0xf4, 0x62, 0x1c, 0x06, 0x53, 0xd7, 0x3a, 0xad, 0x0d, 0x12, 0x61, 0x5e, 0xc7, 0xfd, 0xf7, - 0x05, 0x38, 0x35, 0x1d, 0x55, 0x1b, 0xfe, 0x36, 0xa9, 0x24, 0x94, 0x7e, 0x7d, 0x07, 0x35, 0xa0, - 0x2f, 0xf1, 0x22, 0x46, 0xae, 0x74, 0x79, 0x65, 0xea, 0x6e, 0xbf, 0xfb, 0xd4, 0xba, 0x17, 0x49, - 0xda, 0x33, 0x83, 0x7b, 0xbb, 0x93, 0x7d, 0xeb, 0x5e, 0x84, 0x29, 0x0b, 0xd4, 0x84, 0xfe, 0x20, - 0x0c, 0x48, 0xb9, 0xc0, 0x58, 0x5d, 0xbb, 0x7b, 0x56, 0xd7, 0xc2, 0x40, 0xf5, 0x63, 0x66, 0x68, - 0x6f, 0x77, 0xb2, 0x9f, 0x42, 0x30, 0xe3, 0x42, 0xfb, 0xf5, 0xb2, 0xdf, 0x2e, 0xf7, 0xd9, 0xea, - 0xd7, 0xf3, 0x7e, 0xdb, 0xec, 0xd7, 0xf3, 0x7e, 0x1b, 0x53, 0x16, 0xee, 0xe7, 0x0b, 0x30, 0x3c, - 0x1d, 0xd5, 0x3b, 0x2d, 0x12, 0x24, 0x31, 0xfa, 0x04, 0x40, 0xdb, 0x8b, 0xbc, 0x16, 0x49, 0x48, - 0x14, 0x97, 0x9d, 0x07, 0xfb, 0x1e, 0x2d, 0x5d, 0x5e, 0xba, 0x7b, 0xf6, 0x6b, 0x92, 0xe6, 0x0c, - 0x12, 0x9f, 0x1c, 0x14, 0x28, 0xc6, 0x1a, 0x4b, 0xf4, 0x0a, 0x0c, 0x7b, 0x51, 0xe2, 0x6f, 0x7a, - 0xd5, 0x24, 0x2e, 0x17, 0x18, 0xff, 0xa7, 0xef, 0x9e, 0xff, 0xb4, 0x20, 0x39, 0x73, 0x5a, 0xb0, - 0x1f, 0x96, 0x90, 0x18, 0xa7, 0xfc, 0xdc, 0xdf, 0xed, 0x87, 0xd2, 0x74, 0x94, 0x2c, 0xcc, 0x56, - 0x12, 0x2f, 0xe9, 0xc4, 0xe8, 0x0f, 0x1c, 0x38, 0x13, 0xf3, 0x61, 0xf3, 0x49, 0xbc, 0x16, 0x85, - 0x55, 0x12, 0xc7, 0xa4, 0x26, 0xc6, 0x65, 0xd3, 0x4a, 0xbb, 0x24, 0xb3, 0xa9, 0x4a, 0x37, 0xa3, - 0x2b, 0x41, 0x12, 0xed, 0xcc, 0x3c, 0x21, 0xda, 0x7c, 0x26, 0x07, 0xe3, 0xf5, 0xb7, 0x26, 0x91, - 0xec, 0x0a, 0xa5, 0xc4, 0x3f, 0x31, 0xce, 0x6b, 0x35, 0xfa, 0x9a, 0x03, 0x23, 0xed, 0xb0, 0x16, - 0x63, 0x52, 0x0d, 0x3b, 0x6d, 0x52, 0x13, 0xc3, 0xfb, 0x51, 0xbb, 0xdd, 0x58, 0xd3, 0x38, 0xf0, - 0xf6, 0x9f, 0x15, 0xed, 0x1f, 0xd1, 0x8b, 0xb0, 0xd1, 0x14, 0xf4, 0x14, 0x8c, 0x04, 0x61, 0x52, - 0x69, 0x93, 0xaa, 0xbf, 0xe9, 0x93, 0x1a, 0x9b, 0xf8, 0x43, 0x69, 0xcd, 0x6b, 0x5a, 0x19, 0x36, - 0x30, 0x27, 0xe6, 0xa1, 0xdc, 0x6b, 0xe4, 0xd0, 0x38, 0xf4, 0x6d, 0x91, 0x1d, 0x2e, 0x6c, 0x30, - 0xfd, 0x17, 0x9d, 0x95, 0x02, 0x88, 0x2e, 0xe3, 0x21, 0x21, 0x59, 0xde, 0x57, 0x78, 0xca, 0x99, - 0xf8, 0x20, 0x9c, 0xee, 0x6a, 0xfa, 0x61, 0x08, 0xb8, 0xdf, 0x1f, 0x80, 0x21, 0xf9, 0x29, 0xd0, - 0x83, 0xd0, 0x1f, 0x78, 0x2d, 0x29, 0xe7, 0x46, 0x44, 0x3f, 0xfa, 0xaf, 0x79, 0x2d, 0xba, 0xc2, - 0xbd, 0x16, 0xa1, 0x18, 0x6d, 0x2f, 0x69, 0x30, 0x3a, 0x1a, 0xc6, 0x9a, 0x97, 0x34, 0x30, 0x2b, - 0x41, 0xf7, 0x43, 0x7f, 0x2b, 0xac, 0x11, 0x36, 0x16, 0x45, 0x2e, 0x21, 0x56, 0xc2, 0x1a, 0xc1, - 0x0c, 0x4a, 0xeb, 0x6f, 0x46, 0x61, 0xab, 0xdc, 0x6f, 0xd6, 0x9f, 0x8f, 0xc2, 0x16, 0x66, 0x25, - 0xe8, 0xab, 0x0e, 0x8c, 0xcb, 0xb9, 0xbd, 0x1c, 0x56, 0xbd, 0xc4, 0x0f, 0x83, 0x72, 0x91, 0x49, - 0x14, 0x6c, 0x6f, 0x49, 0x49, 0xca, 0x33, 0x65, 0xd1, 0x84, 0xf1, 0x6c, 0x09, 0xee, 0x6a, 0x05, - 0xba, 0x0c, 0x50, 0x6f, 0x86, 0x1b, 0x5e, 0x93, 0x0e, 0x48, 0x79, 0x80, 0x75, 0x41, 0x49, 0x86, - 0x05, 0x55, 0x82, 0x35, 0x2c, 0x74, 0x0b, 0x06, 0x3d, 0x2e, 0xfd, 0xcb, 0x83, 0xac, 0x13, 0xcf, - 0xd8, 0xe8, 0x84, 0xb1, 0x9d, 0xcc, 0x94, 0xf6, 0x76, 0x27, 0x07, 0x05, 0x10, 0x4b, 0x76, 0xe8, - 0x71, 0x18, 0x0a, 0xdb, 0xb4, 0xdd, 0x5e, 0xb3, 0x3c, 0xc4, 0x26, 0xe6, 0xb8, 0x68, 0xeb, 0xd0, - 0xaa, 0x80, 0x63, 0x85, 0x81, 0x1e, 0x83, 0xc1, 0xb8, 0xb3, 0x41, 0xbf, 0x63, 0x79, 0x98, 0x75, - 0xec, 0x94, 0x40, 0x1e, 0xac, 0x70, 0x30, 0x96, 0xe5, 0xe8, 0xbd, 0x50, 0x8a, 0x48, 0xb5, 0x13, - 0xc5, 0x84, 0x7e, 0xd8, 0x32, 0x30, 0xda, 0x67, 0x04, 0x7a, 0x09, 0xa7, 0x45, 0x58, 0xc7, 0x43, - 0x1f, 0x80, 0x31, 0xfa, 0x81, 0xaf, 0xdc, 0x6a, 0x47, 0x24, 0x8e, 0xe9, 0x57, 0x2d, 0x31, 0x46, - 0xe7, 0x45, 0xcd, 0xb1, 0x79, 0xa3, 0x14, 0x67, 0xb0, 0xd1, 0xab, 0x00, 0x9e, 0x92, 0x19, 0xe5, - 0x11, 0x36, 0x98, 0xcb, 0xf6, 0x66, 0xc4, 0xc2, 0xec, 0xcc, 0x18, 0xfd, 0x8e, 0xe9, 0x6f, 0xac, - 0xf1, 0xa3, 0xe3, 0x53, 0x23, 0x4d, 0x92, 0x90, 0x5a, 0x79, 0x94, 0x75, 0x58, 0x8d, 0xcf, 0x1c, - 0x07, 0x63, 0x59, 0xee, 0xfe, 0x46, 0x01, 0x34, 0x2a, 0x68, 0x06, 0x86, 0x84, 0x5c, 0x13, 0x4b, - 0x72, 0xe6, 0x11, 0xf9, 0x1d, 0xe4, 0x17, 0xbc, 0xbd, 0x9b, 0x2b, 0x0f, 0x55, 0x3d, 0xf4, 0x1a, - 0x94, 0xda, 0x61, 0x6d, 0x85, 0x24, 0x5e, 0xcd, 0x4b, 0x3c, 0xb1, 0x9b, 0x5b, 0xd8, 0x61, 0x24, - 0xc5, 0x99, 0x53, 0xf4, 0xd3, 0xad, 0xa5, 0x2c, 0xb0, 0xce, 0x0f, 0x3d, 0x0d, 0x28, 0x26, 0xd1, - 0xb6, 0x5f, 0x25, 0xd3, 0xd5, 0x2a, 0x55, 0x89, 0xd8, 0x02, 0xe8, 0x63, 0x9d, 0x99, 0x10, 0x9d, - 0x41, 0x95, 0x2e, 0x0c, 0x9c, 0x53, 0xcb, 0xfd, 0x41, 0x01, 0xc6, 0xb4, 0xbe, 0xb6, 0x49, 0x15, - 0x7d, 0xc7, 0x81, 0x53, 0x6a, 0x3b, 0x9b, 0xd9, 0xb9, 0x46, 0x67, 0x15, 0xdf, 0xac, 0x88, 0xcd, - 0xef, 0x4b, 0x79, 0xa9, 0x9f, 0x82, 0x0f, 0x97, 0xf5, 0x17, 0x44, 0x1f, 0x4e, 0x65, 0x4a, 0x71, - 0xb6, 0x59, 0x13, 0x5f, 0x71, 0xe0, 0x6c, 0x1e, 0x89, 0x1c, 0x99, 0xdb, 0xd0, 0x65, 0xae, 0x55, - 0xe1, 0x45, 0xb9, 0xd2, 0xce, 0xe8, 0x72, 0xfc, 0xff, 0x17, 0x60, 0x5c, 0x9f, 0x42, 0x4c, 0x13, - 0xf8, 0x57, 0x0e, 0x9c, 0x93, 0x3d, 0xc0, 0x24, 0xee, 0x34, 0x33, 0xc3, 0xdb, 0xb2, 0x3a, 0xbc, - 0x7c, 0x27, 0x9d, 0xce, 0xe3, 0xc7, 0x87, 0xf9, 0x01, 0x31, 0xcc, 0xe7, 0x72, 0x71, 0x70, 0x7e, - 0x53, 0x27, 0xbe, 0xe5, 0xc0, 0x44, 0x6f, 0xa2, 0x39, 0x03, 0xdf, 0x36, 0x07, 0xfe, 0x79, 0x7b, - 0x9d, 0xe4, 0xec, 0xd9, 0xf0, 0xb3, 0xce, 0xea, 0x1f, 0xe0, 0xb7, 0x86, 0xa0, 0x6b, 0x0f, 0x41, - 0x4f, 0x40, 0x49, 0x88, 0xe3, 0xe5, 0xb0, 0x1e, 0xb3, 0x46, 0x0e, 0xf1, 0xb5, 0x36, 0x9d, 0x82, - 0xb1, 0x8e, 0x83, 0x6a, 0x50, 0x88, 0x9f, 0x14, 0x4d, 0xb7, 0x20, 0xde, 0x2a, 0x4f, 0x2a, 0x2d, - 0x72, 0x60, 0x6f, 0x77, 0xb2, 0x50, 0x79, 0x12, 0x17, 0xe2, 0x27, 0xa9, 0xa6, 0x5e, 0xf7, 0x13, - 0x7b, 0x9a, 0xfa, 0x82, 0x9f, 0x28, 0x3e, 0x4c, 0x53, 0x5f, 0xf0, 0x13, 0x4c, 0x59, 0xd0, 0x13, - 0x48, 0x23, 0x49, 0xda, 0x6c, 0xc7, 0xb7, 0x72, 0x02, 0xb9, 0xba, 0xbe, 0xbe, 0xa6, 0x78, 0x31, - 0xfd, 0x82, 0x42, 0x30, 0xe3, 0x82, 0xde, 0x70, 0xe8, 0x88, 0xf3, 0xc2, 0x30, 0xda, 0x11, 0x8a, - 0xc3, 0x75, 0x7b, 0x53, 0x20, 0x8c, 0x76, 0x14, 0x73, 0xf1, 0x21, 0x55, 0x01, 0xd6, 0x59, 0xb3, - 0x8e, 0xd7, 0x36, 0x63, 0xa6, 0x27, 0xd8, 0xe9, 0xf8, 0xdc, 0x7c, 0x25, 0xd3, 0xf1, 0xb9, 0xf9, - 0x0a, 0x66, 0x5c, 0xe8, 0x07, 0x8d, 0xbc, 0x9b, 0x42, 0xc7, 0xb0, 0xf0, 0x41, 0xb1, 0x77, 0xd3, - 0xfc, 0xa0, 0xd8, 0xbb, 0x89, 0x29, 0x0b, 0xca, 0x29, 0x8c, 0x63, 0xa6, 0x52, 0x58, 0xe1, 0xb4, - 0x5a, 0xa9, 0x98, 0x9c, 0x56, 0x2b, 0x15, 0x4c, 0x59, 0xb0, 0x49, 0x5a, 0x8d, 0x99, 0x3e, 0x62, - 0x67, 0x92, 0xce, 0x66, 0x38, 0x2d, 0xcc, 0x56, 0x30, 0x65, 0x41, 0x45, 0x86, 0xf7, 0x72, 0x27, - 0xe2, 0xca, 0x4c, 0xe9, 0xf2, 0xaa, 0x85, 0xf9, 0x42, 0xc9, 0x29, 0x6e, 0xc3, 0x7b, 0xbb, 0x93, - 0x45, 0x06, 0xc2, 0x9c, 0x91, 0xfb, 0xfb, 0x7d, 0xa9, 0xb8, 0x90, 0xf2, 0x1c, 0xfd, 0x2a, 0xdb, - 0x08, 0x85, 0x2c, 0x10, 0xaa, 0xaf, 0x73, 0x6c, 0xaa, 0xef, 0x19, 0xbe, 0xe3, 0x19, 0xec, 0x70, - 0x96, 0x3f, 0xfa, 0x92, 0xd3, 0x7d, 0xb6, 0xf5, 0xec, 0xef, 0x65, 0xe9, 0xc6, 0xcc, 0xf7, 0x8a, - 0x7d, 0x8f, 0xbc, 0x13, 0x6f, 0x38, 0xa9, 0x12, 0x11, 0xf7, 0xda, 0x07, 0x3e, 0x66, 0xee, 0x03, - 0x16, 0x0f, 0xe4, 0xba, 0xdc, 0xff, 0xbc, 0x03, 0xa3, 0x12, 0x4e, 0xd5, 0xe3, 0x18, 0xdd, 0x82, - 0x21, 0xd9, 0x52, 0xf1, 0xf5, 0x6c, 0xda, 0x02, 0x94, 0x12, 0xaf, 0x1a, 0xa3, 0xb8, 0xb9, 0xdf, - 0x19, 0x00, 0x94, 0xee, 0x55, 0xed, 0x30, 0xf6, 0x99, 0x24, 0x3a, 0xc2, 0x2e, 0x14, 0x68, 0xbb, - 0xd0, 0xb3, 0x36, 0x77, 0xa1, 0xb4, 0x59, 0xc6, 0x7e, 0xf4, 0xa5, 0x8c, 0xdc, 0xe6, 0x1b, 0xd3, - 0x47, 0x8f, 0x45, 0x6e, 0x6b, 0x4d, 0xd8, 0x5f, 0x82, 0x6f, 0x0b, 0x09, 0xce, 0xb7, 0xae, 0x5f, - 0xb0, 0x2b, 0xc1, 0xb5, 0x56, 0x64, 0x65, 0x79, 0xc4, 0x25, 0x2c, 0xdf, 0xbb, 0x6e, 0x58, 0x95, - 0xb0, 0x1a, 0x57, 0x53, 0xd6, 0x46, 0x5c, 0xd6, 0x0e, 0xd8, 0xe2, 0xa9, 0xc9, 0xda, 0x2c, 0x4f, - 0x25, 0x75, 0x5f, 0x96, 0x52, 0x97, 0xef, 0x5a, 0xcf, 0x59, 0x96, 0xba, 0x1a, 0xdf, 0x6e, 0xf9, - 0xfb, 0x12, 0x9c, 0xeb, 0xc6, 0xc3, 0x64, 0x13, 0x5d, 0x82, 0xe1, 0x6a, 0x18, 0x6c, 0xfa, 0xf5, - 0x15, 0xaf, 0x2d, 0xce, 0x6b, 0x4a, 0x16, 0xcd, 0xca, 0x02, 0x9c, 0xe2, 0xa0, 0x07, 0xb8, 0xe0, - 0xe1, 0x16, 0x91, 0x92, 0x40, 0xed, 0x5b, 0x22, 0x3b, 0x4c, 0x0a, 0xbd, 0x6f, 0xe8, 0xab, 0xdf, - 0x98, 0xbc, 0xe7, 0x93, 0xff, 0xf1, 0xc1, 0x7b, 0xdc, 0x3f, 0xec, 0x83, 0xfb, 0x72, 0x79, 0x0a, - 0x6d, 0xfd, 0xb7, 0x0c, 0x6d, 0x5d, 0x2b, 0x17, 0x52, 0xe4, 0x86, 0x4d, 0x45, 0x56, 0x23, 0x9f, - 0xa7, 0x97, 0x6b, 0xc5, 0x38, 0xbf, 0x51, 0x74, 0xa0, 0x02, 0xaf, 0x45, 0xe2, 0xb6, 0x57, 0x25, - 0xa2, 0xf7, 0x6a, 0xa0, 0xae, 0xc9, 0x02, 0x9c, 0xe2, 0xf0, 0x23, 0xf4, 0xa6, 0xd7, 0x69, 0x26, - 0xc2, 0x50, 0xa6, 0x1d, 0xa1, 0x19, 0x18, 0xcb, 0x72, 0xf4, 0xf7, 0x1d, 0x40, 0xdd, 0x5c, 0xc5, - 0x42, 0x5c, 0x3f, 0x8e, 0x71, 0x98, 0x39, 0xbf, 0xa7, 0x1d, 0xc2, 0xb5, 0x9e, 0xe6, 0xb4, 0x43, - 0xfb, 0xa6, 0x1f, 0x4f, 0xf7, 0x21, 0x7e, 0x38, 0x38, 0x80, 0x0d, 0x8d, 0x99, 0x5a, 0xaa, 0x55, - 0x12, 0xc7, 0xdc, 0x1c, 0xa7, 0x9b, 0x5a, 0x18, 0x18, 0xcb, 0x72, 0x34, 0x09, 0x45, 0x12, 0x45, - 0x61, 0x24, 0xce, 0xda, 0x6c, 0x1a, 0x5f, 0xa1, 0x00, 0xcc, 0xe1, 0xee, 0x8f, 0x0b, 0x50, 0xee, - 0x75, 0x3a, 0x41, 0xbf, 0xa3, 0x9d, 0xab, 0xc5, 0xc9, 0x49, 0x1c, 0xfc, 0xc2, 0xe3, 0x3b, 0x13, - 0x65, 0x0f, 0x80, 0x3d, 0x4e, 0xd8, 0xa2, 0x14, 0x67, 0x1b, 0x38, 0xf1, 0xa6, 0x76, 0xc2, 0xd6, - 0x49, 0xe4, 0x6c, 0xf0, 0x9b, 0xe6, 0x06, 0xbf, 0x66, 0xbb, 0x53, 0xfa, 0x36, 0xff, 0xc7, 0x45, - 0x38, 0x23, 0x4b, 0x2b, 0x84, 0x6e, 0x95, 0xcf, 0x74, 0x48, 0xb4, 0x83, 0xfe, 0xc8, 0x81, 0xb3, - 0x5e, 0xd6, 0x74, 0xe3, 0x93, 0x63, 0x18, 0x68, 0x8d, 0xeb, 0xd4, 0x74, 0x0e, 0x47, 0x3e, 0xd0, - 0x97, 0xc5, 0x40, 0x9f, 0xcd, 0x43, 0xe9, 0x61, 0x77, 0xcf, 0xed, 0x00, 0x7a, 0x0a, 0x46, 0x24, - 0x9c, 0x99, 0x7b, 0xf8, 0x12, 0x57, 0xc6, 0xed, 0x69, 0xad, 0x0c, 0x1b, 0x98, 0xb4, 0x66, 0x42, - 0x5a, 0xed, 0xa6, 0x97, 0x10, 0xcd, 0x50, 0xa4, 0x6a, 0xae, 0x6b, 0x65, 0xd8, 0xc0, 0x44, 0x8f, - 0xc0, 0x40, 0x10, 0xd6, 0xc8, 0x62, 0x4d, 0x18, 0x88, 0xc7, 0x44, 0x9d, 0x81, 0x6b, 0x0c, 0x8a, - 0x45, 0x29, 0x7a, 0x38, 0xb5, 0xc6, 0x15, 0xd9, 0x12, 0x2a, 0xe5, 0x59, 0xe2, 0xd0, 0x3f, 0x72, - 0x60, 0x98, 0xd6, 0x58, 0xdf, 0x69, 0x13, 0xba, 0xb7, 0xd1, 0x2f, 0x52, 0x3b, 0x9e, 0x2f, 0x72, - 0x4d, 0xb2, 0x31, 0x4d, 0x1d, 0xc3, 0x0a, 0xfe, 0xfa, 0x5b, 0x93, 0x43, 0xf2, 0x07, 0x4e, 0x5b, - 0x35, 0xb1, 0x00, 0xf7, 0xf6, 0xfc, 0x9a, 0x87, 0x72, 0x05, 0xfc, 0x2d, 0x18, 0x33, 0x1b, 0x71, - 0x28, 0x3f, 0xc0, 0xbf, 0xd0, 0x96, 0x1d, 0xef, 0x97, 0x90, 0x67, 0x6f, 0x9b, 0x36, 0xab, 0x26, - 0xc3, 0x9c, 0x98, 0x7a, 0xe6, 0x64, 0x98, 0x13, 0x93, 0x61, 0xce, 0xfd, 0x03, 0x27, 0x5d, 0x9a, - 0x9a, 0x9a, 0x47, 0x37, 0xe6, 0x4e, 0xd4, 0x14, 0x82, 0x58, 0x6d, 0xcc, 0xd7, 0xf1, 0x32, 0xa6, - 0x70, 0xf4, 0xa6, 0x26, 0x1d, 0x69, 0xb5, 0x8e, 0x70, 0x6b, 0x58, 0x32, 0xd1, 0x1b, 0x84, 0xbb, - 0xe5, 0x9f, 0x28, 0xc0, 0xd9, 0x26, 0xb8, 0x5f, 0x2a, 0xc0, 0x03, 0xfb, 0x2a, 0xad, 0xb9, 0x0d, - 0x77, 0xde, 0xf6, 0x86, 0xd3, 0x6d, 0x2d, 0x22, 0xed, 0xf0, 0x3a, 0x5e, 0x16, 0xdf, 0x4b, 0x6d, - 0x6b, 0x98, 0x83, 0xb1, 0x2c, 0xa7, 0xaa, 0xc3, 0x16, 0xd9, 0x99, 0x0f, 0xa3, 0x96, 0x97, 0x08, - 0xe9, 0xa0, 0x54, 0x87, 0x25, 0x59, 0x80, 0x53, 0x1c, 0xf7, 0x8f, 0x1c, 0xc8, 0x36, 0x00, 0x79, - 0x30, 0xd6, 0x89, 0x49, 0x44, 0xb7, 0xd4, 0x0a, 0xa9, 0x46, 0x44, 0x4e, 0xcf, 0x87, 0xa7, 0xb8, - 0xb7, 0x9f, 0xf6, 0x70, 0xaa, 0x1a, 0x46, 0x64, 0x6a, 0xfb, 0x89, 0x29, 0x8e, 0xb1, 0x44, 0x76, - 0x2a, 0xa4, 0x49, 0x28, 0x8d, 0x19, 0xb4, 0xb7, 0x3b, 0x39, 0x76, 0xdd, 0x20, 0x80, 0x33, 0x04, - 0x29, 0x8b, 0xb6, 0x17, 0xc7, 0x37, 0xc3, 0xa8, 0x26, 0x58, 0x14, 0x0e, 0xcd, 0x62, 0xcd, 0x20, - 0x80, 0x33, 0x04, 0xdd, 0x1f, 0xd0, 0xe3, 0xa3, 0xae, 0xb5, 0xa2, 0x6f, 0x50, 0xdd, 0x87, 0x42, - 0x66, 0x9a, 0xe1, 0xc6, 0x6c, 0x18, 0x24, 0x9e, 0x1f, 0x10, 0x19, 0x2c, 0xb0, 0x6e, 0x49, 0x47, - 0x36, 0x68, 0xa7, 0x36, 0xfc, 0xee, 0x32, 0x9c, 0xd3, 0x16, 0xaa, 0xe3, 0x6c, 0x34, 0xc3, 0x8d, - 0xac, 0x17, 0x90, 0x22, 0x61, 0x56, 0xe2, 0xfe, 0xd4, 0x81, 0x0b, 0x3d, 0x94, 0x71, 0xf4, 0x15, - 0x07, 0x46, 0x37, 0x7e, 0x26, 0xfa, 0x66, 0x36, 0x03, 0x7d, 0x00, 0xc6, 0x28, 0x80, 0xee, 0x44, - 0x62, 0x6e, 0x16, 0x4c, 0x0f, 0xd5, 0x8c, 0x51, 0x8a, 0x33, 0xd8, 0xee, 0xaf, 0x15, 0x20, 0x87, - 0x0b, 0x7a, 0x1c, 0x86, 0x48, 0x50, 0x6b, 0x87, 0x7e, 0x90, 0x08, 0x61, 0xa4, 0xa4, 0xde, 0x15, - 0x01, 0xc7, 0x0a, 0x43, 0x9c, 0x3f, 0xc4, 0xc0, 0x14, 0xba, 0xce, 0x1f, 0xa2, 0xe5, 0x29, 0x0e, - 0xaa, 0xc3, 0xb8, 0xc7, 0xfd, 0x2b, 0x6c, 0xee, 0xb1, 0x69, 0xda, 0x77, 0x98, 0x69, 0x7a, 0x96, - 0xb9, 0x3f, 0x33, 0x24, 0x70, 0x17, 0x51, 0xf4, 0x5e, 0x28, 0x75, 0x62, 0x52, 0x99, 0x5b, 0x9a, - 0x8d, 0x48, 0x8d, 0x9f, 0x8a, 0x35, 0xbf, 0xdf, 0xf5, 0xb4, 0x08, 0xeb, 0x78, 0xee, 0x9f, 0x38, - 0x30, 0x38, 0xe3, 0x55, 0xb7, 0xc2, 0xcd, 0x4d, 0x3a, 0x14, 0xb5, 0x4e, 0x94, 0x1a, 0xb6, 0xb4, - 0xa1, 0x98, 0x13, 0x70, 0xac, 0x30, 0xd0, 0x3a, 0x0c, 0xf0, 0x05, 0x2f, 0x96, 0xdd, 0xbb, 0xb5, - 0xfe, 0xa8, 0x38, 0x1e, 0x36, 0x1d, 0x3a, 0x89, 0xdf, 0x9c, 0xe2, 0x71, 0x3c, 0x53, 0x8b, 0x41, - 0xb2, 0x1a, 0x55, 0x92, 0xc8, 0x0f, 0xea, 0x33, 0x40, 0xb7, 0x8b, 0x79, 0x46, 0x03, 0x0b, 0x5a, - 0xb4, 0x1b, 0x2d, 0xef, 0x96, 0x64, 0x27, 0xc4, 0x8f, 0xea, 0xc6, 0x4a, 0x5a, 0x84, 0x75, 0x3c, - 0xba, 0x9b, 0x54, 0xbd, 0xb6, 0xd0, 0x4b, 0xd4, 0x6e, 0x32, 0xeb, 0xb5, 0x31, 0x85, 0xbb, 0x7f, - 0xe8, 0xc0, 0xf0, 0x8c, 0x17, 0xfb, 0xd5, 0xbf, 0x44, 0xb2, 0xe9, 0x23, 0x50, 0x9c, 0xf5, 0xaa, - 0x0d, 0x82, 0xae, 0x67, 0xcf, 0xc4, 0xa5, 0xcb, 0x8f, 0xe6, 0xb1, 0x51, 0xe7, 0x63, 0x9d, 0xd3, - 0x68, 0xaf, 0x93, 0xb3, 0xfb, 0x96, 0x03, 0x63, 0xb3, 0x4d, 0x9f, 0x04, 0xc9, 0x2c, 0x89, 0x12, - 0x36, 0x70, 0x75, 0x18, 0xaf, 0x2a, 0xc8, 0x51, 0x86, 0x8e, 0x4d, 0xe6, 0xd9, 0x0c, 0x09, 0xdc, - 0x45, 0x14, 0xd5, 0xe0, 0x14, 0x87, 0xa5, 0x8b, 0xe6, 0x50, 0xe3, 0xc7, 0x8c, 0xa7, 0xb3, 0x26, - 0x05, 0x9c, 0x25, 0xe9, 0xfe, 0xc4, 0x81, 0x0b, 0xb3, 0xcd, 0x4e, 0x9c, 0x90, 0xe8, 0x86, 0x10, - 0x56, 0x52, 0xfb, 0x45, 0x1f, 0x83, 0xa1, 0x96, 0x74, 0xe8, 0x3a, 0x77, 0x98, 0xdf, 0x4c, 0xdc, - 0x51, 0x6c, 0xda, 0x98, 0xd5, 0x8d, 0x17, 0x49, 0x35, 0x59, 0x21, 0x89, 0x97, 0x46, 0x1f, 0xa4, - 0x30, 0xac, 0xa8, 0xa2, 0x36, 0xf4, 0xc7, 0x6d, 0x52, 0xb5, 0x17, 0xfc, 0x25, 0xfb, 0x50, 0x69, - 0x93, 0x6a, 0x2a, 0xf6, 0x99, 0x2b, 0x92, 0x71, 0x72, 0xff, 0x8f, 0x03, 0xf7, 0xf5, 0xe8, 0xef, - 0xb2, 0x1f, 0x27, 0xe8, 0x85, 0xae, 0x3e, 0x4f, 0x1d, 0xac, 0xcf, 0xb4, 0x36, 0xeb, 0xb1, 0x92, - 0x17, 0x12, 0xa2, 0xf5, 0xf7, 0xe3, 0x50, 0xf4, 0x13, 0xd2, 0x92, 0x56, 0x6a, 0x0b, 0xf6, 0xa4, - 0x1e, 0x7d, 0x99, 0x19, 0x95, 0x21, 0x80, 0x8b, 0x94, 0x1f, 0xe6, 0x6c, 0xdd, 0x2d, 0x18, 0x98, - 0x0d, 0x9b, 0x9d, 0x56, 0x70, 0xb0, 0x40, 0x9a, 0x64, 0xa7, 0x4d, 0xb2, 0x5b, 0x28, 0x3b, 0x1d, - 0xb0, 0x12, 0x69, 0x57, 0xea, 0xcb, 0xb7, 0x2b, 0xb9, 0xff, 0xda, 0x01, 0xba, 0xaa, 0x6a, 0xbe, - 0x70, 0x34, 0x72, 0x72, 0x9c, 0xe1, 0x03, 0x3a, 0xb9, 0xdb, 0xbb, 0x93, 0xa3, 0x0a, 0x51, 0xa3, - 0xff, 0x11, 0x18, 0x88, 0xd9, 0x89, 0x5d, 0xb4, 0x61, 0x5e, 0xaa, 0xd7, 0xfc, 0x1c, 0x7f, 0x7b, - 0x77, 0xf2, 0x40, 0x51, 0x9d, 0x53, 0x8a, 0xb6, 0xf0, 0x89, 0x0a, 0xaa, 0x54, 0x1f, 0x6c, 0x91, - 0x38, 0xf6, 0xea, 0xf2, 0x00, 0xa8, 0xf4, 0xc1, 0x15, 0x0e, 0xc6, 0xb2, 0xdc, 0xfd, 0xb2, 0x03, - 0xa3, 0x6a, 0x6f, 0xa3, 0xda, 0x3d, 0xba, 0xa6, 0xef, 0x82, 0x7c, 0xa6, 0x3c, 0xd0, 0x43, 0xe2, - 0x88, 0x7d, 0x7e, 0xff, 0x4d, 0xf2, 0x3d, 0x30, 0x52, 0x23, 0x6d, 0x12, 0xd4, 0x48, 0x50, 0xa5, - 0xa7, 0x73, 0x3a, 0x43, 0x86, 0x67, 0xc6, 0xe9, 0x71, 0x74, 0x4e, 0x83, 0x63, 0x03, 0xcb, 0xfd, - 0xa6, 0x03, 0xf7, 0x2a, 0x72, 0x15, 0x92, 0x60, 0x92, 0x44, 0x3b, 0x2a, 0x8a, 0xf3, 0x70, 0x9b, - 0xd9, 0x0d, 0xaa, 0x1e, 0x27, 0x11, 0x67, 0x7e, 0xb4, 0xdd, 0xac, 0xc4, 0x95, 0x69, 0x46, 0x04, - 0x4b, 0x6a, 0xee, 0xaf, 0xf4, 0xc1, 0x59, 0xbd, 0x91, 0x4a, 0xc0, 0x7c, 0xca, 0x01, 0x50, 0x23, - 0x40, 0xf7, 0xeb, 0x3e, 0x3b, 0xae, 0x2d, 0xe3, 0x4b, 0xa5, 0x22, 0x48, 0x81, 0x63, 0xac, 0xb1, - 0x45, 0xcf, 0xc1, 0xc8, 0x36, 0x5d, 0x14, 0x64, 0x85, 0x6a, 0x13, 0x71, 0xb9, 0x8f, 0x35, 0x63, - 0x32, 0xef, 0x63, 0x3e, 0x9b, 0xe2, 0xa5, 0xd6, 0x02, 0x0d, 0x18, 0x63, 0x83, 0x14, 0x3d, 0x08, - 0x8d, 0x46, 0xfa, 0x27, 0x11, 0x26, 0xf3, 0x0f, 0x5b, 0xec, 0x63, 0xf6, 0xab, 0xcf, 0x9c, 0xde, - 0xdb, 0x9d, 0x1c, 0x35, 0x40, 0xd8, 0x6c, 0x84, 0xfb, 0x1c, 0xb0, 0xb1, 0xf0, 0x83, 0x0e, 0x59, - 0x0d, 0xd0, 0x43, 0xd2, 0x84, 0xc7, 0xdd, 0x2e, 0x4a, 0x72, 0xe8, 0x66, 0x3c, 0x7a, 0xd4, 0xdd, - 0xf4, 0xfc, 0x26, 0x8b, 0x6e, 0xa4, 0x58, 0xea, 0xa8, 0x3b, 0xcf, 0xa0, 0x58, 0x94, 0xba, 0x53, - 0x30, 0x38, 0x4b, 0xfb, 0x4e, 0x22, 0x4a, 0x57, 0x0f, 0x4a, 0x1e, 0x35, 0x82, 0x92, 0x65, 0xf0, - 0xf1, 0x3a, 0x9c, 0x9b, 0x8d, 0x88, 0x97, 0x90, 0xca, 0x93, 0x33, 0x9d, 0xea, 0x16, 0x49, 0x78, - 0xe4, 0x57, 0x8c, 0xde, 0x0f, 0xa3, 0x21, 0xdb, 0x32, 0x96, 0xc3, 0xea, 0x96, 0x1f, 0xd4, 0x85, - 0x45, 0xf6, 0x9c, 0xa0, 0x32, 0xba, 0xaa, 0x17, 0x62, 0x13, 0xd7, 0xfd, 0xcf, 0x05, 0x18, 0x99, - 0x8d, 0xc2, 0x40, 0x8a, 0xc5, 0x13, 0xd8, 0xca, 0x12, 0x63, 0x2b, 0xb3, 0xe0, 0x0d, 0xd5, 0xdb, - 0xdf, 0x6b, 0x3b, 0x43, 0xaf, 0x2a, 0x11, 0xd9, 0x67, 0xeb, 0x84, 0x62, 0xf0, 0x65, 0xb4, 0xd3, - 0x8f, 0x6d, 0x0a, 0x50, 0xf7, 0xbf, 0x38, 0x30, 0xae, 0xa3, 0x9f, 0xc0, 0x0e, 0x1a, 0x9b, 0x3b, - 0xe8, 0x35, 0xbb, 0xfd, 0xed, 0xb1, 0x6d, 0xbe, 0x35, 0x68, 0xf6, 0x93, 0xb9, 0xc2, 0xbf, 0xea, - 0xc0, 0xc8, 0x4d, 0x0d, 0x20, 0x3a, 0x6b, 0x5b, 0x89, 0x79, 0x87, 0x14, 0x33, 0x3a, 0xf4, 0x76, - 0xe6, 0x37, 0x36, 0x5a, 0x42, 0xe5, 0x7e, 0x5c, 0x6d, 0x90, 0x5a, 0xa7, 0x29, 0xb7, 0x6f, 0x35, - 0xa4, 0x15, 0x01, 0xc7, 0x0a, 0x03, 0xbd, 0x00, 0xa7, 0xab, 0x61, 0x50, 0xed, 0x44, 0x11, 0x09, - 0xaa, 0x3b, 0x6b, 0xec, 0x0a, 0x85, 0xd8, 0x10, 0xa7, 0x44, 0xb5, 0xd3, 0xb3, 0x59, 0x84, 0xdb, - 0x79, 0x40, 0xdc, 0x4d, 0x88, 0xfb, 0x12, 0x62, 0xba, 0x65, 0x89, 0xf3, 0x98, 0xe6, 0x4b, 0x60, - 0x60, 0x2c, 0xcb, 0xd1, 0x75, 0xb8, 0x10, 0x27, 0x5e, 0x94, 0xf8, 0x41, 0x7d, 0x8e, 0x78, 0xb5, - 0xa6, 0x1f, 0xd0, 0xa3, 0x44, 0x18, 0xd4, 0xb8, 0xa7, 0xb1, 0x6f, 0xe6, 0xbe, 0xbd, 0xdd, 0xc9, - 0x0b, 0x95, 0x7c, 0x14, 0xdc, 0xab, 0x2e, 0xfa, 0x08, 0x4c, 0x08, 0x6f, 0xc5, 0x66, 0xa7, 0xf9, - 0x74, 0xb8, 0x11, 0x5f, 0xf5, 0x63, 0x7a, 0xcc, 0x5f, 0xf6, 0x5b, 0x7e, 0xc2, 0xfc, 0x89, 0xc5, - 0x99, 0x8b, 0x7b, 0xbb, 0x93, 0x13, 0x95, 0x9e, 0x58, 0x78, 0x1f, 0x0a, 0x08, 0xc3, 0x79, 0x2e, - 0xfc, 0xba, 0x68, 0x0f, 0x32, 0xda, 0x13, 0x7b, 0xbb, 0x93, 0xe7, 0xe7, 0x73, 0x31, 0x70, 0x8f, - 0x9a, 0xf4, 0x0b, 0x26, 0x7e, 0x8b, 0xbc, 0x1c, 0x06, 0x84, 0xc5, 0xb1, 0x68, 0x5f, 0x70, 0x5d, - 0xc0, 0xb1, 0xc2, 0x40, 0x2f, 0xa6, 0x33, 0x91, 0x2e, 0x17, 0x11, 0x8f, 0x72, 0x78, 0x09, 0xc7, - 0x8e, 0x26, 0x37, 0x34, 0x4a, 0x2c, 0xd0, 0xd2, 0xa0, 0x8d, 0x3e, 0xed, 0xc0, 0x48, 0x9c, 0x84, - 0xea, 0xda, 0x83, 0x08, 0x48, 0xb1, 0x30, 0xed, 0x2b, 0x1a, 0x55, 0xae, 0xf8, 0xe8, 0x10, 0x6c, - 0x70, 0x45, 0xef, 0x84, 0x61, 0x39, 0x81, 0xe3, 0x72, 0x89, 0xe9, 0x4a, 0xec, 0x18, 0x27, 0xe7, - 0x77, 0x8c, 0xd3, 0x72, 0xaa, 0xca, 0xde, 0x6c, 0x90, 0x80, 0x85, 0xe4, 0x6a, 0xaa, 0xec, 0x8d, - 0x06, 0x09, 0x30, 0x2b, 0x71, 0x7f, 0xdc, 0x07, 0xa8, 0x5b, 0xf0, 0xa1, 0x25, 0x18, 0xf0, 0xaa, - 0x89, 0xbf, 0x2d, 0xc3, 0x11, 0x1f, 0xca, 0x53, 0x0a, 0xf8, 0x00, 0x62, 0xb2, 0x49, 0xe8, 0xbc, - 0x27, 0xa9, 0xb4, 0x9c, 0x66, 0x55, 0xb1, 0x20, 0x81, 0x42, 0x38, 0xdd, 0xf4, 0xe2, 0x44, 0xb6, - 0xb0, 0x46, 0x3f, 0xa4, 0xd8, 0x2e, 0x7e, 0xfe, 0x60, 0x9f, 0x8a, 0xd6, 0x98, 0x39, 0x47, 0xd7, - 0xe3, 0x72, 0x96, 0x10, 0xee, 0xa6, 0x8d, 0x3e, 0xc1, 0xb4, 0x2b, 0xae, 0xfa, 0x4a, 0xb5, 0x66, - 0xc9, 0x8a, 0xe6, 0xc1, 0x69, 0x1a, 0x9a, 0x95, 0x60, 0x83, 0x35, 0x96, 0xe8, 0x12, 0x0c, 0xb3, - 0x75, 0x43, 0x6a, 0x84, 0xaf, 0xfe, 0xbe, 0x54, 0x09, 0xae, 0xc8, 0x02, 0x9c, 0xe2, 0x68, 0x5a, - 0x06, 0x5f, 0xf0, 0x3d, 0xb4, 0x0c, 0xf4, 0x14, 0x14, 0xdb, 0x0d, 0x2f, 0x96, 0x21, 0xee, 0xae, - 0x94, 0xda, 0x6b, 0x14, 0xc8, 0x44, 0x93, 0xf6, 0x2d, 0x19, 0x10, 0xf3, 0x0a, 0xee, 0xbf, 0x01, - 0x18, 0x9c, 0x9b, 0x5e, 0x58, 0xf7, 0xe2, 0xad, 0x03, 0x9c, 0x81, 0xe8, 0x32, 0x14, 0xca, 0x6a, - 0x56, 0x90, 0x4a, 0x25, 0x16, 0x2b, 0x0c, 0x14, 0xc0, 0x80, 0x1f, 0x50, 0xc9, 0x53, 0x1e, 0xb3, - 0xe5, 0x86, 0x50, 0xe7, 0x39, 0x66, 0x27, 0x5a, 0x64, 0xd4, 0xb1, 0xe0, 0x82, 0x5e, 0x85, 0x61, - 0x4f, 0xde, 0x30, 0x12, 0xfb, 0xff, 0x92, 0x0d, 0xfb, 0xba, 0x20, 0xa9, 0x47, 0x38, 0x09, 0x10, - 0x4e, 0x19, 0xa2, 0x4f, 0x3a, 0x50, 0x92, 0x5d, 0xc7, 0x64, 0x53, 0xb8, 0xbe, 0x57, 0xec, 0xf5, - 0x19, 0x93, 0x4d, 0x1e, 0xfe, 0xa2, 0x01, 0xb0, 0xce, 0xb2, 0xeb, 0xcc, 0x54, 0x3c, 0xc8, 0x99, - 0x09, 0xdd, 0x84, 0xe1, 0x9b, 0x7e, 0xd2, 0x60, 0x3b, 0xbc, 0x70, 0xb9, 0xcd, 0xdf, 0x7d, 0xab, - 0x29, 0xb9, 0x74, 0xc4, 0x6e, 0x48, 0x06, 0x38, 0xe5, 0x45, 0x97, 0x03, 0xfd, 0xc1, 0x6e, 0x68, - 0xb1, 0xbd, 0x61, 0xd8, 0xac, 0xc0, 0x0a, 0x70, 0x8a, 0x43, 0x87, 0x78, 0x84, 0xfe, 0xaa, 0x90, - 0x97, 0x3a, 0x54, 0xb4, 0x88, 0x90, 0x46, 0x0b, 0xf3, 0x4a, 0x52, 0xe4, 0x83, 0x75, 0x43, 0xe3, - 0x81, 0x0d, 0x8e, 0x4a, 0x74, 0x0e, 0xf7, 0x12, 0x9d, 0xe8, 0x55, 0x7e, 0x86, 0xe3, 0x87, 0x09, - 0xb1, 0x1b, 0x2c, 0xdb, 0x39, 0xdf, 0x70, 0x9a, 0xfc, 0xd6, 0x43, 0xfa, 0x1b, 0x6b, 0xfc, 0xa8, - 0xc4, 0x08, 0x83, 0x2b, 0xb7, 0xfc, 0x44, 0xdc, 0xd5, 0x50, 0x12, 0x63, 0x95, 0x41, 0xb1, 0x28, - 0xe5, 0xa1, 0x1d, 0x74, 0x12, 0xc4, 0x62, 0x17, 0xd0, 0x42, 0x3b, 0x18, 0x18, 0xcb, 0x72, 0xf4, - 0x0f, 0x1c, 0x28, 0x36, 0xc2, 0x70, 0x2b, 0x2e, 0x8f, 0xb2, 0xc9, 0x61, 0x41, 0xa7, 0x16, 0x12, - 0x67, 0xea, 0x2a, 0x25, 0x6b, 0xde, 0x3e, 0x2b, 0x32, 0xd8, 0xed, 0xdd, 0xc9, 0xb1, 0x65, 0x7f, - 0x93, 0x54, 0x77, 0xaa, 0x4d, 0xc2, 0x20, 0xaf, 0xbf, 0xa5, 0x41, 0xae, 0x6c, 0x93, 0x20, 0xc1, - 0xbc, 0x55, 0x13, 0x9f, 0x77, 0x00, 0x52, 0x42, 0x39, 0x3e, 0x54, 0x62, 0x46, 0x1d, 0x58, 0x38, - 0x50, 0x1b, 0x4d, 0xd3, 0x9d, 0xb2, 0xff, 0xce, 0x81, 0x12, 0xed, 0x9c, 0x14, 0x81, 0x8f, 0xc0, - 0x40, 0xe2, 0x45, 0x75, 0x22, 0xfd, 0x08, 0xea, 0x73, 0xac, 0x33, 0x28, 0x16, 0xa5, 0x28, 0x80, - 0x62, 0xe2, 0xc5, 0x5b, 0x52, 0x8d, 0x5f, 0xb4, 0x36, 0xc4, 0xa9, 0x06, 0x4f, 0x7f, 0xc5, 0x98, - 0xb3, 0x41, 0x8f, 0xc2, 0x10, 0xdd, 0x3a, 0xe6, 0xbd, 0x58, 0x86, 0xf6, 0x8c, 0x50, 0x21, 0x3e, - 0x2f, 0x60, 0x58, 0x95, 0xba, 0xbf, 0x56, 0x80, 0xfe, 0x39, 0x7e, 0xa0, 0x1b, 0x88, 0xc3, 0x4e, - 0x54, 0x25, 0x42, 0xb1, 0xb7, 0x30, 0xa7, 0x29, 0xdd, 0x0a, 0xa3, 0xa9, 0x1d, 0xa9, 0xd8, 0x6f, - 0x2c, 0x78, 0xa1, 0x37, 0x1d, 0x18, 0x4b, 0x22, 0x2f, 0x88, 0x37, 0x99, 0xc7, 0xc6, 0x0f, 0x03, - 0x31, 0x44, 0x16, 0x66, 0xe1, 0xba, 0x41, 0xb7, 0x92, 0x90, 0x76, 0xea, 0x38, 0x32, 0xcb, 0x70, - 0xa6, 0x0d, 0xee, 0xaf, 0x3b, 0x00, 0x69, 0xeb, 0xd1, 0x1b, 0x0e, 0x8c, 0x7a, 0x7a, 0x48, 0xa9, - 0x18, 0xa3, 0x55, 0x7b, 0xee, 0x5d, 0x46, 0x96, 0xdb, 0x32, 0x0c, 0x10, 0x36, 0x19, 0xbb, 0xef, - 0x85, 0x22, 0x5b, 0x1d, 0xec, 0xd0, 0x23, 0x6c, 0xdf, 0x59, 0x63, 0x97, 0xb4, 0x89, 0x63, 0x85, - 0xe1, 0xbe, 0x00, 0x63, 0x57, 0x6e, 0x91, 0x6a, 0x27, 0x09, 0x23, 0x6e, 0xf9, 0xef, 0x71, 0x85, - 0xc8, 0x39, 0xd2, 0x15, 0xa2, 0xef, 0x3a, 0x50, 0xd2, 0xe2, 0x0b, 0xe9, 0x4e, 0x5d, 0x9f, 0xad, - 0x70, 0x03, 0x87, 0x18, 0xaa, 0x25, 0x2b, 0x11, 0x8c, 0x9c, 0x64, 0xba, 0x8d, 0x28, 0x10, 0x4e, - 0x19, 0xde, 0x21, 0xfe, 0xcf, 0xfd, 0x7d, 0x07, 0xce, 0xe5, 0x06, 0x43, 0xbe, 0xcd, 0xcd, 0x36, - 0x7c, 0xf0, 0x85, 0x03, 0xf8, 0xe0, 0x7f, 0xdb, 0x81, 0x94, 0x12, 0x15, 0x45, 0x1b, 0x69, 0xcb, - 0x35, 0x51, 0x24, 0x38, 0x89, 0x52, 0xf4, 0x2a, 0x5c, 0x30, 0xbf, 0xe0, 0x11, 0xfd, 0x2d, 0xfc, - 0x70, 0x9a, 0x4f, 0x09, 0xf7, 0x62, 0xe1, 0x7e, 0xcd, 0x81, 0xe2, 0x82, 0xd7, 0xa9, 0x93, 0x03, - 0x99, 0xcb, 0xa8, 0x1c, 0x8b, 0x88, 0xd7, 0x4c, 0xe4, 0xd1, 0x41, 0xc8, 0x31, 0x2c, 0x60, 0x58, - 0x95, 0xa2, 0x69, 0x18, 0x0e, 0xdb, 0xc4, 0x70, 0x21, 0x3e, 0x24, 0x47, 0x6f, 0x55, 0x16, 0xd0, - 0x6d, 0x87, 0x71, 0x57, 0x10, 0x9c, 0xd6, 0x72, 0xbf, 0x3e, 0x00, 0x25, 0xed, 0xda, 0x0c, 0xd5, - 0x05, 0x22, 0xd2, 0x0e, 0xb3, 0xfa, 0x32, 0x9d, 0x30, 0x98, 0x95, 0xd0, 0x35, 0x18, 0x91, 0x6d, - 0x3f, 0xe6, 0x62, 0xcb, 0x58, 0x83, 0x58, 0xc0, 0xb1, 0xc2, 0x40, 0x93, 0x50, 0xac, 0x91, 0x76, - 0xd2, 0x60, 0xcd, 0xeb, 0xe7, 0xb1, 0x83, 0x73, 0x14, 0x80, 0x39, 0x9c, 0x22, 0x6c, 0x92, 0xa4, - 0xda, 0x60, 0x96, 0x61, 0x11, 0x5c, 0x38, 0x4f, 0x01, 0x98, 0xc3, 0x73, 0xbc, 0x98, 0xc5, 0xe3, - 0xf7, 0x62, 0x0e, 0x58, 0xf6, 0x62, 0xa2, 0x36, 0x9c, 0x89, 0xe3, 0xc6, 0x5a, 0xe4, 0x6f, 0x7b, - 0x09, 0x49, 0x67, 0xdf, 0xe0, 0x61, 0xf8, 0x5c, 0x60, 0x17, 0xd9, 0x2b, 0x57, 0xb3, 0x54, 0x70, - 0x1e, 0x69, 0x54, 0x81, 0x73, 0x7e, 0x10, 0x93, 0x6a, 0x27, 0x22, 0x8b, 0xf5, 0x20, 0x8c, 0xc8, - 0xd5, 0x30, 0xa6, 0xe4, 0xc4, 0x35, 0x5c, 0x15, 0x6e, 0xbb, 0x98, 0x87, 0x84, 0xf3, 0xeb, 0xa2, - 0x05, 0x38, 0x5d, 0xf3, 0x63, 0x6f, 0xa3, 0x49, 0x2a, 0x9d, 0x8d, 0x56, 0xc8, 0x8f, 0xe6, 0xc3, - 0x8c, 0xe0, 0xbd, 0xd2, 0x8e, 0x34, 0x97, 0x45, 0xc0, 0xdd, 0x75, 0xd0, 0x53, 0x30, 0x12, 0xfb, - 0x41, 0xbd, 0x49, 0x66, 0x22, 0x2f, 0xa8, 0x36, 0xc4, 0xfd, 0x5d, 0x65, 0x6f, 0xaf, 0x68, 0x65, - 0xd8, 0xc0, 0x64, 0x6b, 0x9e, 0xd7, 0xc9, 0x68, 0x83, 0x02, 0x5b, 0x94, 0xa2, 0x69, 0x38, 0x25, - 0xfb, 0x50, 0xd9, 0xf2, 0xdb, 0xeb, 0xcb, 0x15, 0xa6, 0x15, 0x0e, 0xa5, 0xc1, 0x44, 0x8b, 0x66, - 0x31, 0xce, 0xe2, 0xbb, 0x3f, 0x74, 0x60, 0x44, 0x8f, 0x96, 0xa7, 0xca, 0x3a, 0x34, 0xe6, 0xe6, - 0x2b, 0x7c, 0x3b, 0xb1, 0xa7, 0x34, 0x5c, 0x55, 0x34, 0xd3, 0xf3, 0x76, 0x0a, 0xc3, 0x1a, 0xcf, - 0x03, 0xdc, 0x7d, 0x7f, 0x08, 0x8a, 0x9b, 0x21, 0xd5, 0x69, 0xfa, 0x4c, 0x5b, 0xff, 0x3c, 0x05, - 0x62, 0x5e, 0xe6, 0xfe, 0x0f, 0x07, 0xce, 0xe7, 0x5f, 0x04, 0xf8, 0x59, 0xe8, 0xe4, 0x65, 0x00, - 0xda, 0x15, 0x63, 0x5f, 0xd0, 0xb2, 0x5f, 0xc8, 0x12, 0xac, 0x61, 0x1d, 0xac, 0xdb, 0xff, 0xb6, - 0x00, 0x1a, 0x4f, 0xf4, 0x05, 0x07, 0x46, 0x29, 0xdb, 0xa5, 0x68, 0xc3, 0xe8, 0xed, 0xaa, 0x9d, - 0xde, 0x2a, 0xb2, 0xa9, 0x4b, 0xc3, 0x00, 0x63, 0x93, 0x39, 0x7a, 0x27, 0x0c, 0x7b, 0xb5, 0x5a, - 0x44, 0xe2, 0x58, 0x39, 0x07, 0x99, 0xc1, 0x6b, 0x5a, 0x02, 0x71, 0x5a, 0x4e, 0xe5, 0x70, 0xa3, - 0xb6, 0x19, 0x53, 0xd1, 0x26, 0x64, 0xbf, 0x92, 0xc3, 0x94, 0x09, 0x85, 0x63, 0x85, 0x81, 0x9e, - 0x85, 0xf3, 0x35, 0x2f, 0xf1, 0xb8, 0x0a, 0x48, 0xa2, 0xb5, 0x28, 0x4c, 0x48, 0x95, 0xed, 0x1b, - 0x3c, 0x96, 0xe4, 0xa2, 0xa8, 0x7b, 0x7e, 0x2e, 0x17, 0x0b, 0xf7, 0xa8, 0xed, 0xfe, 0x72, 0x3f, - 0x98, 0x7d, 0x42, 0x35, 0x38, 0xb5, 0x15, 0x6d, 0xcc, 0xb2, 0x98, 0x8d, 0xa3, 0xc4, 0x4e, 0xb0, - 0x98, 0x86, 0x25, 0x93, 0x02, 0xce, 0x92, 0x14, 0x5c, 0x96, 0xc8, 0x4e, 0xe2, 0x6d, 0x1c, 0x39, - 0x72, 0x62, 0xc9, 0xa4, 0x80, 0xb3, 0x24, 0xd1, 0x7b, 0xa1, 0xb4, 0x15, 0x6d, 0xc8, 0xdd, 0x23, - 0x1b, 0xa5, 0xb3, 0x94, 0x16, 0x61, 0x1d, 0x8f, 0x7e, 0x9a, 0xad, 0x68, 0x83, 0x6e, 0xd8, 0x32, - 0xc7, 0x84, 0xfa, 0x34, 0x4b, 0x02, 0x8e, 0x15, 0x06, 0x6a, 0x03, 0xda, 0x92, 0xa3, 0xa7, 0x22, - 0x54, 0xc4, 0x26, 0x77, 0xf0, 0x00, 0x17, 0x76, 0x73, 0x60, 0xa9, 0x8b, 0x0e, 0xce, 0xa1, 0x8d, - 0x9e, 0x83, 0x0b, 0x5b, 0xd1, 0x86, 0xd0, 0x63, 0xd6, 0x22, 0x3f, 0xa8, 0xfa, 0x6d, 0x23, 0x9f, - 0xc4, 0xa4, 0x68, 0xee, 0x85, 0xa5, 0x7c, 0x34, 0xdc, 0xab, 0xbe, 0xfb, 0x3b, 0xfd, 0xc0, 0x6e, - 0xc2, 0x52, 0x31, 0xdd, 0x22, 0x49, 0x23, 0xac, 0x65, 0x55, 0xb3, 0x15, 0x06, 0xc5, 0xa2, 0x54, - 0xc6, 0xc7, 0x16, 0x7a, 0xc4, 0xc7, 0xde, 0x84, 0xc1, 0x06, 0xf1, 0x6a, 0x24, 0x92, 0xc6, 0xcd, - 0x65, 0x3b, 0x77, 0x77, 0xaf, 0x32, 0xa2, 0xa9, 0x85, 0x80, 0xff, 0x8e, 0xb1, 0xe4, 0x86, 0xde, - 0x07, 0x63, 0x54, 0xc7, 0x0a, 0x3b, 0x89, 0xf4, 0x4f, 0x70, 0xe3, 0x26, 0xdb, 0xec, 0xd7, 0x8d, - 0x12, 0x9c, 0xc1, 0x44, 0x73, 0x30, 0x2e, 0x7c, 0x09, 0xca, 0x68, 0x2a, 0x06, 0x56, 0x25, 0xfa, - 0xa8, 0x64, 0xca, 0x71, 0x57, 0x0d, 0x16, 0xdf, 0x18, 0xd6, 0xb8, 0x3b, 0x59, 0x8f, 0x6f, 0x0c, - 0x6b, 0x3b, 0x98, 0x95, 0xa0, 0x97, 0x61, 0x88, 0xfe, 0x9d, 0x8f, 0xc2, 0x96, 0x30, 0x1b, 0xad, - 0xd9, 0x19, 0x1d, 0xca, 0x43, 0x1c, 0x62, 0x99, 0xee, 0x39, 0x23, 0xb8, 0x60, 0xc5, 0x8f, 0x1e, - 0xa5, 0xf4, 0xed, 0xf2, 0x59, 0x12, 0xf9, 0x9b, 0x3b, 0x4c, 0x9f, 0x19, 0x4a, 0x8f, 0x52, 0x8b, - 0x5d, 0x18, 0x38, 0xa7, 0x96, 0xfb, 0x85, 0x02, 0x8c, 0xe8, 0x17, 0xaa, 0xef, 0x14, 0x34, 0x1d, - 0xa7, 0x93, 0x82, 0x1f, 0x9c, 0xaf, 0x5a, 0xe8, 0xf6, 0x9d, 0x26, 0x44, 0x03, 0xfa, 0xbd, 0x8e, - 0x50, 0x64, 0xad, 0xd8, 0xe7, 0x58, 0x8f, 0x3b, 0x49, 0x83, 0xdf, 0xbc, 0x63, 0xe1, 0xcc, 0x8c, - 0x83, 0xfb, 0x99, 0x3e, 0x18, 0x92, 0x85, 0xe8, 0xd3, 0x0e, 0x40, 0x1a, 0x37, 0x26, 0x44, 0xe9, - 0x9a, 0x8d, 0xa0, 0x22, 0x3d, 0xe4, 0x4d, 0x33, 0xf3, 0x2b, 0x38, 0xd6, 0xf8, 0xa2, 0x04, 0x06, - 0x42, 0xda, 0xb8, 0xcb, 0xf6, 0x92, 0x02, 0xac, 0x52, 0xc6, 0x97, 0x19, 0xf7, 0xd4, 0xa2, 0xc7, - 0x60, 0x58, 0xf0, 0xa2, 0x87, 0xd3, 0x0d, 0x19, 0xce, 0x68, 0xcf, 0xfa, 0xad, 0x22, 0x24, 0xd3, - 0xb3, 0xa6, 0x02, 0xe1, 0x94, 0xa1, 0xfb, 0x04, 0x8c, 0x99, 0x8b, 0x81, 0x1e, 0x56, 0x36, 0x76, - 0x12, 0xc2, 0x4d, 0x21, 0x23, 0xfc, 0xb0, 0x32, 0x43, 0x01, 0x98, 0xc3, 0xdd, 0x1f, 0x38, 0x00, - 0xa9, 0x78, 0x39, 0x80, 0xf7, 0xe1, 0x21, 0xdd, 0x8e, 0xd7, 0xeb, 0x44, 0xf8, 0x09, 0x18, 0x66, - 0xff, 0xb0, 0x85, 0xde, 0x67, 0x2b, 0xf8, 0x20, 0x6d, 0xa7, 0x58, 0xea, 0x4c, 0xd7, 0x78, 0x56, - 0x32, 0xc2, 0x29, 0x4f, 0x37, 0x84, 0xf1, 0x2c, 0x36, 0xfa, 0x30, 0x8c, 0xc4, 0x72, 0x5b, 0x4d, - 0xaf, 0x07, 0x1e, 0x70, 0xfb, 0xe5, 0xae, 0x3f, 0xad, 0x3a, 0x36, 0x88, 0xb9, 0xab, 0x30, 0x60, - 0x75, 0x08, 0xdd, 0x6f, 0x3b, 0x30, 0xcc, 0xbc, 0xaf, 0xf5, 0xc8, 0x6b, 0xa5, 0x55, 0xfa, 0xf6, - 0x19, 0xf5, 0x18, 0x06, 0xb9, 0xf9, 0x40, 0x46, 0x2d, 0x59, 0x90, 0x32, 0x3c, 0x97, 0x5f, 0x2a, - 0x65, 0xb8, 0x9d, 0x22, 0xc6, 0x92, 0x93, 0xfb, 0xd9, 0x02, 0x0c, 0x2c, 0x06, 0xed, 0xce, 0x5f, - 0xf9, 0x7c, 0x72, 0x2b, 0xd0, 0xbf, 0x98, 0x90, 0x96, 0x99, 0xf6, 0x70, 0x64, 0xe6, 0x61, 0x3d, - 0xe5, 0x61, 0xd9, 0x4c, 0x79, 0x88, 0xbd, 0x9b, 0x32, 0xa8, 0x4f, 0x98, 0xaf, 0xd3, 0x2b, 0x92, - 0x8f, 0xc3, 0xf0, 0xb2, 0xb7, 0x41, 0x9a, 0x4b, 0x64, 0x87, 0x5d, 0x68, 0xe4, 0x01, 0x26, 0x4e, - 0x6a, 0x73, 0x30, 0x82, 0x41, 0xe6, 0x60, 0x8c, 0x61, 0xab, 0xc5, 0x40, 0x4f, 0x24, 0x24, 0xcd, - 0x19, 0xe5, 0x98, 0x27, 0x12, 0x2d, 0x5f, 0x94, 0x86, 0xe5, 0x4e, 0x41, 0x29, 0xa5, 0x72, 0x00, - 0xae, 0x3f, 0x2d, 0xc0, 0xa8, 0x61, 0x85, 0x37, 0x7c, 0x93, 0xce, 0x1d, 0x7d, 0x93, 0x86, 0xaf, - 0xb0, 0xf0, 0x76, 0xfb, 0x0a, 0xfb, 0x4e, 0xde, 0x57, 0x68, 0x7e, 0xa4, 0xfe, 0x03, 0x7d, 0xa4, - 0x37, 0x1d, 0xe8, 0x5f, 0xf6, 0x83, 0xad, 0x83, 0x09, 0x9a, 0xb8, 0x1a, 0xb6, 0xbb, 0x04, 0x4d, - 0x85, 0x02, 0x31, 0x2f, 0x93, 0xaa, 0x4b, 0x5f, 0x0f, 0xd5, 0x25, 0x75, 0x9e, 0xf4, 0xef, 0xe7, - 0x3c, 0x71, 0x3f, 0xed, 0xc0, 0xc8, 0x8a, 0x17, 0xf8, 0x9b, 0x24, 0x4e, 0xd8, 0x04, 0x4c, 0x8e, - 0xf5, 0x06, 0xdc, 0x48, 0x8f, 0x5c, 0x0e, 0xaf, 0x3b, 0x70, 0x7a, 0x85, 0xb4, 0x42, 0xff, 0x65, - 0x2f, 0x0d, 0xae, 0xa5, 0x7d, 0x6c, 0xf8, 0x89, 0x88, 0x25, 0x54, 0x7d, 0xbc, 0xea, 0x27, 0x98, - 0xc2, 0xef, 0x60, 0x8b, 0x66, 0x77, 0x4b, 0xe8, 0x49, 0x4e, 0xbb, 0x95, 0x99, 0x86, 0xcd, 0xca, - 0x02, 0x9c, 0xe2, 0xb8, 0xbf, 0xeb, 0xc0, 0x20, 0x6f, 0x84, 0x8a, 0x47, 0x76, 0x7a, 0xd0, 0x6e, - 0x40, 0x91, 0xd5, 0x13, 0xd3, 0x7f, 0xc1, 0x82, 0x9e, 0x44, 0xc9, 0xf1, 0xc5, 0xca, 0xfe, 0xc5, - 0x9c, 0x01, 0x3b, 0xdf, 0x78, 0xb7, 0xa6, 0x55, 0x5c, 0x71, 0x7a, 0xbe, 0x61, 0x50, 0x2c, 0x4a, - 0xdd, 0xaf, 0xf7, 0xc1, 0x90, 0x4a, 0x61, 0xc6, 0x12, 0x4c, 0x04, 0x41, 0x98, 0x78, 0x3c, 0x5e, - 0x83, 0x0b, 0xf5, 0x0f, 0xdb, 0x4b, 0xa1, 0x36, 0x35, 0x9d, 0x52, 0xe7, 0x3e, 0x48, 0x75, 0x5a, - 0xd5, 0x4a, 0xb0, 0xde, 0x08, 0xf4, 0x71, 0x18, 0x68, 0x52, 0x31, 0x25, 0x65, 0xfc, 0xb3, 0x16, - 0x9b, 0xc3, 0xe4, 0x9f, 0x68, 0x89, 0x1a, 0x21, 0x0e, 0xc4, 0x82, 0xeb, 0xc4, 0x07, 0x60, 0x3c, - 0xdb, 0xea, 0x3b, 0x5d, 0x1a, 0x1d, 0xd6, 0xaf, 0x9c, 0xfe, 0x4d, 0x21, 0x66, 0x0f, 0x5f, 0xd5, - 0x7d, 0x06, 0x4a, 0x2b, 0x24, 0x89, 0xfc, 0x2a, 0x23, 0x70, 0xa7, 0xc9, 0x75, 0x20, 0x45, 0xe3, - 0x73, 0x6c, 0xb2, 0x52, 0x9a, 0x31, 0x7a, 0x15, 0xa0, 0x1d, 0x85, 0xf4, 0xa0, 0x4b, 0x3a, 0xf2, - 0x63, 0x5b, 0x50, 0x9c, 0xd7, 0x14, 0x4d, 0xee, 0x36, 0x4f, 0x7f, 0x63, 0x8d, 0x9f, 0xfb, 0x86, - 0x03, 0xc5, 0x95, 0x4e, 0x42, 0x6e, 0x1d, 0x40, 0xb4, 0x1d, 0x3a, 0x8d, 0xc2, 0xe3, 0x30, 0x44, - 0x3f, 0xf0, 0x86, 0x17, 0x4b, 0x83, 0x5b, 0x1a, 0x76, 0x2e, 0xe0, 0x58, 0x61, 0xb8, 0x1f, 0x86, - 0x11, 0xd6, 0x92, 0xab, 0x61, 0x93, 0x6e, 0xd7, 0x74, 0x24, 0x5b, 0xf4, 0x77, 0xd6, 0x0f, 0xc2, - 0x90, 0x30, 0x2f, 0xa3, 0x2b, 0xac, 0x11, 0x36, 0x6b, 0xea, 0x02, 0x9a, 0x9a, 0x3f, 0x57, 0x19, - 0x14, 0x8b, 0x52, 0xf7, 0x53, 0x05, 0x28, 0xb1, 0x8a, 0x42, 0x3a, 0xed, 0xc0, 0x60, 0x83, 0xf3, - 0x11, 0x43, 0x6e, 0x21, 0x6e, 0x4d, 0x6f, 0xbd, 0x76, 0x46, 0xe4, 0x00, 0x2c, 0xf9, 0x51, 0xd6, - 0x37, 0x3d, 0x3f, 0xa1, 0xac, 0x0b, 0xc7, 0xcb, 0xfa, 0x06, 0x67, 0x83, 0x25, 0x3f, 0xf7, 0x17, - 0x81, 0x5d, 0xec, 0x9e, 0x6f, 0x7a, 0x75, 0x3e, 0x72, 0xe1, 0x16, 0xa9, 0x09, 0x11, 0xad, 0x8d, - 0x1c, 0x85, 0x62, 0x51, 0xca, 0x2f, 0xcb, 0x26, 0x91, 0xaf, 0x22, 0xbe, 0xb5, 0xcb, 0xb2, 0x0c, - 0x2c, 0xe3, 0xfb, 0x6b, 0xee, 0x97, 0x0b, 0x00, 0x2c, 0x3f, 0x1e, 0xbf, 0x8f, 0xfd, 0x6e, 0x19, - 0x9c, 0x65, 0xfa, 0x4e, 0x55, 0x70, 0x16, 0xbb, 0x71, 0xae, 0x07, 0x65, 0xe9, 0x17, 0x31, 0x0a, - 0xfb, 0x5f, 0xc4, 0x40, 0x6d, 0x18, 0x0c, 0x3b, 0x09, 0xd5, 0x81, 0x85, 0x12, 0x61, 0x21, 0x74, - 0x60, 0x95, 0x13, 0xe4, 0xb7, 0x17, 0xc4, 0x0f, 0x2c, 0xd9, 0xa0, 0xa7, 0x60, 0xa8, 0x1d, 0x85, - 0x75, 0xaa, 0x13, 0x88, 0x7d, 0xf9, 0x7e, 0x39, 0x9b, 0xd7, 0x04, 0xfc, 0xb6, 0xf6, 0x3f, 0x56, - 0xd8, 0xee, 0x3f, 0x3c, 0xcd, 0xc7, 0x45, 0xcc, 0xbd, 0x09, 0x28, 0xf8, 0xd2, 0xe2, 0x05, 0x82, - 0x44, 0x61, 0x71, 0x0e, 0x17, 0xfc, 0x9a, 0x5a, 0x85, 0x85, 0x9e, 0xab, 0xf0, 0xbd, 0x50, 0xaa, - 0xf9, 0x71, 0xbb, 0xe9, 0xed, 0x5c, 0xcb, 0x31, 0x37, 0xce, 0xa5, 0x45, 0x58, 0xc7, 0x43, 0x8f, - 0x8b, 0x6b, 0x37, 0xfd, 0x86, 0x89, 0x49, 0x5e, 0xbb, 0x49, 0xef, 0xfb, 0xf3, 0x1b, 0x37, 0xd9, - 0xbc, 0x08, 0xc5, 0x03, 0xe7, 0x45, 0xc8, 0x6a, 0x78, 0x03, 0x27, 0xaf, 0xe1, 0xbd, 0x1f, 0x46, - 0xe5, 0x4f, 0xa6, 0x75, 0x95, 0xcf, 0xb2, 0xd6, 0x2b, 0xf3, 0xfa, 0xba, 0x5e, 0x88, 0x4d, 0xdc, - 0x74, 0xd2, 0x0e, 0x1e, 0x74, 0xd2, 0x5e, 0x06, 0xd8, 0x08, 0x3b, 0x41, 0xcd, 0x8b, 0x76, 0x16, - 0xe7, 0x44, 0x90, 0xae, 0x52, 0x28, 0x67, 0x54, 0x09, 0xd6, 0xb0, 0xf4, 0x89, 0x3e, 0x7c, 0x87, - 0x89, 0xfe, 0x61, 0x18, 0x66, 0x01, 0xcd, 0xa4, 0x36, 0x9d, 0x88, 0xa8, 0xaa, 0xc3, 0x44, 0x89, - 0xa6, 0x71, 0x96, 0x92, 0x08, 0x4e, 0xe9, 0xa1, 0x8f, 0x00, 0x6c, 0xfa, 0x81, 0x1f, 0x37, 0x18, - 0xf5, 0xd2, 0xa1, 0xa9, 0xab, 0x7e, 0xce, 0x2b, 0x2a, 0x58, 0xa3, 0x88, 0x5e, 0x80, 0xd3, 0x24, - 0x4e, 0xfc, 0x96, 0x97, 0x90, 0x9a, 0xba, 0xc7, 0x5a, 0x66, 0x36, 0x52, 0x15, 0x52, 0x7e, 0x25, - 0x8b, 0x70, 0x3b, 0x0f, 0x88, 0xbb, 0x09, 0x19, 0x2b, 0x72, 0xe2, 0x30, 0x2b, 0x12, 0xfd, 0x6f, - 0x07, 0x4e, 0x47, 0x84, 0x87, 0xda, 0xc4, 0xaa, 0x61, 0xe7, 0x98, 0x38, 0xae, 0xda, 0x48, 0x3d, - 0xaf, 0x72, 0xcc, 0xe0, 0x2c, 0x17, 0xae, 0xe7, 0x10, 0xd9, 0xfb, 0xae, 0xf2, 0xdb, 0x79, 0xc0, - 0xd7, 0xdf, 0x9a, 0x9c, 0xec, 0x7e, 0x02, 0x41, 0x11, 0xa7, 0x2b, 0xef, 0xef, 0xbe, 0x35, 0x39, - 0x2e, 0x7f, 0xa7, 0x83, 0xd6, 0xd5, 0x49, 0xba, 0xad, 0xb6, 0xc3, 0xda, 0xe2, 0x9a, 0x08, 0x7f, - 0x53, 0xdb, 0xea, 0x1a, 0x05, 0x62, 0x5e, 0x86, 0x1e, 0xa5, 0x3b, 0x37, 0x69, 0x85, 0x81, 0x4a, - 0x22, 0x3c, 0xc2, 0x77, 0x6d, 0x0e, 0xc3, 0xaa, 0x94, 0x1e, 0x39, 0x02, 0xb1, 0xa5, 0x94, 0xef, - 0xb3, 0x75, 0xe4, 0x90, 0x9b, 0x14, 0xe7, 0x2a, 0x7f, 0x61, 0xc5, 0x09, 0x35, 0x61, 0xc0, 0x67, - 0x06, 0x10, 0x11, 0x61, 0x6b, 0xc1, 0xea, 0xc2, 0x0d, 0x2a, 0x32, 0xbe, 0x96, 0x89, 0x7e, 0xc1, - 0x43, 0xdf, 0x6b, 0x4e, 0x9d, 0xcc, 0x5e, 0xf3, 0x28, 0x0c, 0x55, 0x1b, 0x7e, 0xb3, 0x16, 0x91, - 0xa0, 0x3c, 0xce, 0x2c, 0x01, 0x6c, 0x24, 0x66, 0x05, 0x0c, 0xab, 0x52, 0xf4, 0x37, 0x60, 0x34, - 0xec, 0x24, 0x4c, 0xb4, 0xd0, 0x71, 0x8a, 0xcb, 0xa7, 0x19, 0x3a, 0x8b, 0x97, 0x5a, 0xd5, 0x0b, - 0xb0, 0x89, 0x47, 0x45, 0x7c, 0x23, 0x8c, 0x59, 0x3a, 0x24, 0x26, 0xe2, 0xcf, 0x9b, 0x22, 0xfe, - 0xaa, 0x56, 0x86, 0x0d, 0x4c, 0xf4, 0x55, 0x07, 0x4e, 0xb7, 0xb2, 0xe7, 0xbd, 0xf2, 0x05, 0x36, - 0x32, 0x15, 0x1b, 0xe7, 0x82, 0x0c, 0x69, 0x1e, 0xe9, 0xde, 0x05, 0xc6, 0xdd, 0x8d, 0x60, 0x89, - 0xc9, 0xe2, 0x9d, 0xa0, 0xda, 0x88, 0xc2, 0xc0, 0x6c, 0xde, 0xbd, 0xb6, 0xee, 0xdb, 0xb1, 0xb5, - 0x9d, 0xc7, 0x62, 0xe6, 0xde, 0xbd, 0xdd, 0xc9, 0x73, 0xb9, 0x45, 0x38, 0xbf, 0x51, 0xe8, 0x43, - 0x30, 0x9e, 0x78, 0xf1, 0x16, 0xd7, 0x97, 0x68, 0x4d, 0x52, 0x2b, 0xdf, 0xcf, 0x83, 0x1c, 0xf6, - 0x76, 0x27, 0xc7, 0xd7, 0x33, 0x65, 0xb8, 0x0b, 0x7b, 0x62, 0x0e, 0xce, 0xe7, 0x4b, 0x98, 0x3b, - 0x1d, 0x71, 0xfa, 0xf4, 0x23, 0xce, 0x3c, 0xdc, 0xdb, 0xb3, 0x5b, 0x74, 0xaf, 0x92, 0xfa, 0xaa, - 0x63, 0xee, 0x55, 0x5d, 0xfa, 0xe5, 0x18, 0x8c, 0xe8, 0xaf, 0x6e, 0xb8, 0xff, 0xaf, 0x0f, 0x20, - 0xb5, 0xe0, 0x23, 0x0f, 0xc6, 0xb8, 0xb7, 0x60, 0x71, 0xee, 0xc8, 0xb9, 0x06, 0x66, 0x0d, 0x02, - 0x38, 0x43, 0x10, 0xb5, 0x00, 0x71, 0x08, 0xff, 0x7d, 0x14, 0xaf, 0x2f, 0x73, 0x92, 0xce, 0x76, - 0x11, 0xc1, 0x39, 0x84, 0x69, 0x8f, 0x92, 0x70, 0x8b, 0x04, 0xd7, 0xf1, 0xf2, 0x51, 0xf2, 0x59, - 0x70, 0x3f, 0xa1, 0x41, 0x00, 0x67, 0x08, 0x22, 0x17, 0x06, 0x98, 0xd1, 0x48, 0x46, 0xb5, 0x33, - 0x01, 0xc5, 0x74, 0x95, 0x18, 0x8b, 0x12, 0xf4, 0x65, 0x07, 0xc6, 0x64, 0x5a, 0x0e, 0x66, 0xa7, - 0x95, 0xf1, 0xec, 0xd7, 0x6d, 0x79, 0x60, 0xae, 0xe8, 0xd4, 0xd3, 0x68, 0x51, 0x03, 0x1c, 0xe3, - 0x4c, 0x23, 0xdc, 0xe7, 0xe0, 0x4c, 0x4e, 0x75, 0x2b, 0x47, 0xe8, 0xef, 0x3a, 0x50, 0xd2, 0xb2, - 0x45, 0xa2, 0x57, 0x61, 0x38, 0xac, 0x58, 0x0f, 0x51, 0x5c, 0xad, 0x74, 0x85, 0x28, 0x2a, 0x10, - 0x4e, 0x19, 0x1e, 0x24, 0xb2, 0x32, 0x37, 0xb5, 0xe5, 0xdb, 0xdc, 0xec, 0x43, 0x47, 0x56, 0xfe, - 0x72, 0x11, 0x52, 0x4a, 0x87, 0x4c, 0x17, 0x93, 0xc6, 0x61, 0x16, 0xf6, 0x8d, 0xc3, 0xac, 0xc1, - 0x29, 0x8f, 0x79, 0xb9, 0x8f, 0x98, 0x24, 0x86, 0x27, 0x0b, 0x36, 0x29, 0xe0, 0x2c, 0x49, 0xca, - 0x25, 0x4e, 0xab, 0x32, 0x2e, 0xfd, 0x87, 0xe6, 0x52, 0x31, 0x29, 0xe0, 0x2c, 0x49, 0xf4, 0x02, - 0x94, 0xab, 0xec, 0x56, 0x33, 0xef, 0xe3, 0xe2, 0xe6, 0xb5, 0x30, 0x59, 0x8b, 0x48, 0x4c, 0x82, - 0x44, 0xa4, 0x83, 0x7b, 0x50, 0x8c, 0x42, 0x79, 0xb6, 0x07, 0x1e, 0xee, 0x49, 0x81, 0x1e, 0x74, - 0x98, 0x9b, 0xdc, 0x4f, 0x76, 0x98, 0x10, 0x11, 0xf1, 0x03, 0xea, 0xa0, 0x53, 0xd1, 0x0b, 0xb1, - 0x89, 0x8b, 0x7e, 0xc9, 0x81, 0xd1, 0xa6, 0x74, 0x24, 0xe0, 0x4e, 0x53, 0xe6, 0x36, 0xc5, 0x56, - 0xa6, 0xdf, 0xb2, 0x4e, 0x99, 0x6b, 0x23, 0x06, 0x08, 0x9b, 0xbc, 0xb3, 0x19, 0x7b, 0x86, 0x0e, - 0x98, 0xb1, 0xe7, 0x07, 0x0e, 0x8c, 0x67, 0xb9, 0xa1, 0x2d, 0x78, 0xa0, 0xe5, 0x45, 0x5b, 0x8b, - 0xc1, 0x66, 0xc4, 0x6e, 0xaf, 0x24, 0x7c, 0x32, 0x4c, 0x6f, 0x26, 0x24, 0x9a, 0xf3, 0x76, 0xb8, - 0x63, 0xb6, 0xa8, 0x1e, 0xc7, 0x7a, 0x60, 0x65, 0x3f, 0x64, 0xbc, 0x3f, 0x2d, 0x54, 0x81, 0x73, - 0x14, 0x81, 0x25, 0xf4, 0xf3, 0xc3, 0x20, 0x65, 0x52, 0x60, 0x4c, 0x54, 0x04, 0xe5, 0x4a, 0x1e, - 0x12, 0xce, 0xaf, 0xeb, 0x5e, 0x81, 0x01, 0x7e, 0x99, 0xf0, 0xae, 0x3c, 0x5b, 0xee, 0x7f, 0x28, - 0x80, 0x54, 0x2d, 0xff, 0x6a, 0x3b, 0x0a, 0xe9, 0x26, 0x1a, 0x31, 0xb5, 0x49, 0xd8, 0x4b, 0xd8, - 0x26, 0x2a, 0x52, 0x67, 0x8a, 0x12, 0xaa, 0x73, 0x93, 0x5b, 0x7e, 0x32, 0x1b, 0xd6, 0xa4, 0x95, - 0x84, 0xe9, 0xdc, 0x57, 0x04, 0x0c, 0xab, 0x52, 0xf7, 0xd3, 0x0e, 0x8c, 0xd2, 0x5e, 0x36, 0x9b, - 0xa4, 0x59, 0x49, 0x48, 0x3b, 0x46, 0x31, 0x14, 0x63, 0xfa, 0x8f, 0x3d, 0x63, 0x62, 0x7a, 0x01, - 0x95, 0xb4, 0x35, 0x2f, 0x12, 0x65, 0x82, 0x39, 0x2f, 0xf7, 0x3b, 0x7d, 0x30, 0xac, 0x06, 0xfb, - 0x00, 0xf6, 0xdb, 0xcb, 0x69, 0x56, 0x5b, 0x2e, 0x81, 0xcb, 0x5a, 0x46, 0xdb, 0xdb, 0x74, 0xe8, - 0x82, 0x1d, 0x9e, 0xbf, 0x23, 0x4d, 0x6f, 0xfb, 0xb8, 0xe9, 0x04, 0x3f, 0xaf, 0xcf, 0x3f, 0x0d, - 0x5f, 0x78, 0xc3, 0x6f, 0xe9, 0x31, 0x08, 0xfd, 0xb6, 0x76, 0x33, 0xe5, 0x60, 0xed, 0x1d, 0x7c, - 0x90, 0x79, 0xf0, 0xa8, 0x78, 0xa0, 0x07, 0x8f, 0x1e, 0x83, 0x7e, 0x12, 0x74, 0x5a, 0x4c, 0x55, - 0x1a, 0x66, 0x87, 0x8c, 0xfe, 0x2b, 0x41, 0xa7, 0x65, 0xf6, 0x8c, 0xa1, 0xa0, 0x0f, 0x40, 0xa9, - 0x46, 0xe2, 0x6a, 0xe4, 0xb3, 0xa4, 0x14, 0xc2, 0x36, 0x74, 0x3f, 0x33, 0xb8, 0xa5, 0x60, 0xb3, - 0xa2, 0x5e, 0xc1, 0x7d, 0x19, 0x06, 0xd6, 0x9a, 0x9d, 0xba, 0x1f, 0xa0, 0x36, 0x0c, 0xf0, 0x14, - 0x15, 0x62, 0xb7, 0xb7, 0x70, 0x72, 0xe5, 0xa2, 0x42, 0x8b, 0x8f, 0xe1, 0xf7, 0x90, 0x05, 0x1f, - 0xf7, 0x53, 0x05, 0xa0, 0x87, 0xfb, 0x85, 0x59, 0xf4, 0xb7, 0xbb, 0xde, 0xf7, 0xf9, 0xb9, 0x9c, - 0xf7, 0x7d, 0x46, 0x19, 0x72, 0xce, 0xd3, 0x3e, 0x4d, 0x18, 0x65, 0xde, 0x18, 0xb9, 0x07, 0x0a, - 0xb5, 0xfa, 0xc9, 0x03, 0x66, 0x75, 0xd0, 0xab, 0x8a, 0x1d, 0x41, 0x07, 0x61, 0x93, 0x38, 0x5a, - 0x81, 0x33, 0x3c, 0x39, 0xea, 0x1c, 0x69, 0x7a, 0x3b, 0x99, 0x24, 0x68, 0xf7, 0xc9, 0x27, 0xdb, - 0xe6, 0xba, 0x51, 0x70, 0x5e, 0x3d, 0xf7, 0xf7, 0xfa, 0x41, 0xf3, 0x81, 0x1c, 0x60, 0xb5, 0xbc, - 0x94, 0xf1, 0x78, 0xad, 0x58, 0xf1, 0x78, 0x49, 0x37, 0x12, 0x97, 0x40, 0xa6, 0x93, 0x8b, 0x36, - 0xaa, 0x41, 0x9a, 0x6d, 0xd1, 0x47, 0xd5, 0xa8, 0xab, 0xa4, 0xd9, 0xc6, 0xac, 0x44, 0xdd, 0xc2, - 0xec, 0xef, 0x79, 0x0b, 0xb3, 0x01, 0xc5, 0xba, 0xd7, 0xa9, 0x13, 0x11, 0x1b, 0x6a, 0xc1, 0xb9, - 0xc9, 0xee, 0x85, 0x70, 0xe7, 0x26, 0xfb, 0x17, 0x73, 0x06, 0x74, 0xb1, 0x37, 0x64, 0xb0, 0x8c, - 0x30, 0xf3, 0x5a, 0x58, 0xec, 0x2a, 0xfe, 0x86, 0x2f, 0x76, 0xf5, 0x13, 0xa7, 0xcc, 0x50, 0x1b, - 0x06, 0xab, 0x3c, 0xb7, 0x8c, 0xd0, 0x59, 0x16, 0x6d, 0x5c, 0x33, 0x65, 0x04, 0xb9, 0x3d, 0x46, - 0xfc, 0xc0, 0x92, 0x8d, 0x7b, 0x09, 0x4a, 0xda, 0x33, 0x23, 0xf4, 0x33, 0xa8, 0xb4, 0x26, 0xda, - 0x67, 0x98, 0xf3, 0x12, 0x0f, 0xb3, 0x12, 0xf7, 0x9b, 0xfd, 0xa0, 0xac, 0x71, 0xfa, 0xa5, 0x48, - 0xaf, 0xaa, 0x25, 0x61, 0x32, 0x12, 0x04, 0x84, 0x01, 0x16, 0xa5, 0x54, 0xaf, 0x6b, 0x91, 0xa8, - 0xae, 0xce, 0xd1, 0x42, 0x5c, 0x2b, 0xbd, 0x6e, 0x45, 0x2f, 0xc4, 0x26, 0x2e, 0x55, 0xca, 0x5b, - 0x22, 0x26, 0x20, 0x1b, 0xf2, 0x2d, 0x63, 0x05, 0xb0, 0xc2, 0x60, 0x59, 0x1c, 0x5a, 0x5a, 0x08, - 0x81, 0x08, 0x11, 0xb5, 0xe1, 0x92, 0xd2, 0xa8, 0xf2, 0x50, 0x2e, 0x1d, 0x82, 0x0d, 0xae, 0x68, - 0x01, 0x4e, 0xc7, 0x24, 0x59, 0xbd, 0x19, 0x90, 0x48, 0xe5, 0x4f, 0x10, 0x69, 0x42, 0xd4, 0x95, - 0x91, 0x4a, 0x16, 0x01, 0x77, 0xd7, 0xc9, 0x8d, 0xaa, 0x2d, 0x1e, 0x3a, 0xaa, 0x76, 0x0e, 0xc6, - 0x37, 0x3d, 0xbf, 0xd9, 0x89, 0x48, 0xcf, 0xd8, 0xdc, 0xf9, 0x4c, 0x39, 0xee, 0xaa, 0xc1, 0x6e, - 0x2d, 0x35, 0xbd, 0x7a, 0x5c, 0x1e, 0xd4, 0x6e, 0x2d, 0x51, 0x00, 0xe6, 0x70, 0xf7, 0x37, 0x1d, - 0xe0, 0xf9, 0x99, 0xa6, 0x37, 0x37, 0xfd, 0xc0, 0x4f, 0x76, 0xd0, 0xd7, 0x1c, 0x18, 0x0f, 0xc2, - 0x1a, 0x99, 0x0e, 0x12, 0x5f, 0x02, 0xed, 0xe5, 0xd4, 0x67, 0xbc, 0xae, 0x65, 0xc8, 0x73, 0x53, - 0x53, 0x16, 0x8a, 0xbb, 0x9a, 0xe1, 0x5e, 0x80, 0x73, 0xb9, 0x04, 0xdc, 0x1f, 0xf4, 0x81, 0x99, - 0x66, 0x0a, 0x3d, 0x03, 0xc5, 0x26, 0x4b, 0x7c, 0xe2, 0x1c, 0x31, 0x7f, 0x18, 0x1b, 0x2b, 0x9e, - 0x19, 0x85, 0x53, 0x42, 0x73, 0x50, 0x62, 0xb9, 0xab, 0x44, 0x5a, 0x9a, 0x82, 0x91, 0xef, 0xa1, - 0x84, 0xd3, 0xa2, 0xdb, 0xe6, 0x4f, 0xac, 0x57, 0x43, 0xaf, 0xc0, 0xe0, 0x06, 0x4f, 0xf0, 0x69, - 0xcf, 0x6b, 0x28, 0x32, 0x86, 0x32, 0xdd, 0x48, 0xa6, 0x0f, 0xbd, 0x9d, 0xfe, 0x8b, 0x25, 0x47, - 0xb4, 0x03, 0x43, 0x9e, 0xfc, 0xa6, 0xfd, 0xb6, 0xae, 0x90, 0x18, 0xf3, 0x47, 0x84, 0xe8, 0xc8, - 0x6f, 0xa8, 0xd8, 0x65, 0x82, 0x9e, 0x8a, 0x07, 0x0a, 0x7a, 0xfa, 0xb6, 0x03, 0x90, 0xbe, 0x86, - 0x82, 0x6e, 0xc1, 0x50, 0xfc, 0xa4, 0x61, 0xa8, 0xb0, 0x91, 0x7e, 0x40, 0x50, 0xd4, 0xae, 0xe8, - 0x0a, 0x08, 0x56, 0xdc, 0xee, 0x64, 0x5c, 0xf9, 0xa9, 0x03, 0x67, 0xf3, 0x5e, 0x6d, 0x79, 0x1b, - 0x5b, 0x7c, 0x58, 0xbb, 0x8a, 0xa8, 0xb0, 0x16, 0x91, 0x4d, 0xff, 0x56, 0x4e, 0x9a, 0x69, 0x5e, - 0x80, 0x53, 0x1c, 0xf7, 0x4f, 0x07, 0x41, 0x31, 0x3e, 0x26, 0x3b, 0xcc, 0x23, 0xf4, 0xcc, 0x54, - 0x4f, 0x75, 0x2e, 0x85, 0x87, 0x19, 0x14, 0x8b, 0x52, 0x7a, 0x6e, 0x92, 0xe1, 0xfa, 0x42, 0x64, - 0xb3, 0x59, 0x28, 0xc3, 0xfa, 0xb1, 0x2a, 0xcd, 0xb3, 0xec, 0x14, 0x4f, 0xc4, 0xb2, 0x33, 0x60, - 0xdf, 0xb2, 0xd3, 0x02, 0x14, 0xf3, 0x85, 0xc2, 0xcc, 0x29, 0x82, 0xd1, 0xc8, 0xa1, 0x0d, 0xcd, - 0x95, 0x2e, 0x22, 0x38, 0x87, 0x30, 0x8b, 0xc2, 0x08, 0x9b, 0x64, 0x1a, 0x5f, 0x13, 0x87, 0x8f, - 0x34, 0x0a, 0x83, 0x83, 0xb1, 0x2c, 0x3f, 0xa2, 0x29, 0x05, 0xfd, 0xb6, 0xb3, 0x8f, 0xad, 0x6a, - 0xd8, 0xd6, 0x16, 0x94, 0x9b, 0xe3, 0x8f, 0x9d, 0xa4, 0x8e, 0x62, 0x00, 0xfb, 0xba, 0x03, 0xa7, - 0x49, 0x50, 0x8d, 0x76, 0x18, 0x1d, 0x41, 0x4d, 0x38, 0xc9, 0xaf, 0xdb, 0x58, 0xeb, 0x57, 0xb2, - 0xc4, 0xb9, 0x2f, 0xaa, 0x0b, 0x8c, 0xbb, 0x9b, 0x81, 0x56, 0x61, 0xa8, 0xea, 0x89, 0x79, 0x51, - 0x3a, 0xcc, 0xbc, 0xe0, 0xae, 0xbe, 0x69, 0x31, 0x1b, 0x14, 0x11, 0xf7, 0xc7, 0x05, 0x38, 0x93, - 0xd3, 0x24, 0x76, 0x93, 0xac, 0x45, 0x17, 0xc0, 0x62, 0x2d, 0xbb, 0xfc, 0x97, 0x04, 0x1c, 0x2b, - 0x0c, 0xb4, 0x06, 0x67, 0xb7, 0x5a, 0x71, 0x4a, 0x65, 0x36, 0x0c, 0x12, 0x72, 0x4b, 0x0a, 0x03, - 0xe9, 0x40, 0x3f, 0xbb, 0x94, 0x83, 0x83, 0x73, 0x6b, 0x52, 0x6d, 0x89, 0x04, 0xde, 0x46, 0x93, - 0xa4, 0x45, 0x22, 0xdc, 0x4b, 0x69, 0x4b, 0x57, 0x32, 0xe5, 0xb8, 0xab, 0x06, 0x7a, 0xc3, 0x81, - 0xfb, 0x62, 0x12, 0x6d, 0x93, 0xa8, 0xe2, 0xd7, 0xc8, 0x6c, 0x27, 0x4e, 0xc2, 0x16, 0x89, 0x8e, - 0x68, 0x9d, 0x9d, 0xdc, 0xdb, 0x9d, 0xbc, 0xaf, 0xd2, 0x9b, 0x1a, 0xde, 0x8f, 0x95, 0xfb, 0x86, - 0x03, 0x63, 0x15, 0x76, 0x76, 0x57, 0xaa, 0xbb, 0xed, 0x2c, 0xaf, 0x8f, 0xa8, 0xa4, 0x22, 0x19, - 0x21, 0x6c, 0xa6, 0x01, 0x71, 0x5f, 0x84, 0xf1, 0x0a, 0x69, 0x79, 0xed, 0x06, 0xbb, 0x5f, 0xcd, - 0x03, 0xc8, 0x2e, 0xc1, 0x70, 0x2c, 0x61, 0xd9, 0x77, 0x9f, 0x14, 0x32, 0x4e, 0x71, 0xd0, 0xc3, - 0x3c, 0xd8, 0x4d, 0x5e, 0x85, 0x1a, 0xe6, 0x87, 0x1c, 0x1e, 0x21, 0x17, 0x63, 0x59, 0xe6, 0x7e, - 0xbb, 0x00, 0x23, 0x69, 0x7d, 0xb2, 0x89, 0xea, 0x70, 0xaa, 0xaa, 0x5d, 0x23, 0x4c, 0x2f, 0x70, - 0x1c, 0xfc, 0xc6, 0x21, 0x4f, 0x3e, 0x6d, 0x12, 0xc1, 0x59, 0xaa, 0x87, 0x8f, 0x2c, 0x7c, 0x25, - 0x13, 0x59, 0x68, 0xe5, 0x41, 0x89, 0xca, 0x4e, 0x50, 0x55, 0x71, 0x89, 0x64, 0x53, 0x86, 0x3c, - 0x74, 0x05, 0x2a, 0x7e, 0xb1, 0x00, 0xa7, 0xd4, 0x38, 0x09, 0x27, 0xe9, 0x6b, 0xd9, 0x78, 0x42, - 0x6c, 0x23, 0x37, 0x93, 0xf9, 0xe1, 0xf7, 0x89, 0x29, 0x7c, 0x2d, 0x1b, 0x53, 0x78, 0xac, 0xec, - 0xbb, 0xfc, 0xbe, 0xdf, 0x2e, 0xc0, 0x90, 0xca, 0x14, 0xf5, 0x0c, 0x14, 0xd9, 0xb1, 0xf9, 0xee, - 0x94, 0x7f, 0x76, 0x04, 0xc7, 0x9c, 0x12, 0x25, 0xc9, 0x62, 0x96, 0x8e, 0x9c, 0x8f, 0x78, 0x98, - 0x1b, 0x4f, 0xbd, 0x28, 0xc1, 0x9c, 0x12, 0x5a, 0x82, 0x3e, 0x12, 0xd4, 0xc4, 0xe4, 0x39, 0x3c, - 0x41, 0xf6, 0x3c, 0xdc, 0x95, 0xa0, 0x86, 0x29, 0x15, 0x96, 0xae, 0x8e, 0x2b, 0x7b, 0x99, 0x80, - 0x7d, 0xa1, 0xe9, 0x89, 0x52, 0x77, 0x06, 0x8c, 0x54, 0x86, 0x47, 0xba, 0x30, 0xf2, 0x4b, 0x7d, - 0x30, 0x50, 0xe9, 0x6c, 0xd0, 0x33, 0xd1, 0xb7, 0x1c, 0x38, 0x73, 0x33, 0x93, 0xf0, 0x3b, 0x5d, - 0xa4, 0xd7, 0xed, 0x19, 0xa1, 0xf5, 0xd8, 0x3b, 0x65, 0x7a, 0xcb, 0x29, 0xc4, 0x79, 0xcd, 0x31, - 0x72, 0xee, 0xf6, 0x1d, 0x4b, 0xce, 0xdd, 0x5b, 0xc7, 0x7c, 0xa9, 0x65, 0xb4, 0xd7, 0x85, 0x16, - 0xf7, 0xf7, 0x8a, 0x00, 0xfc, 0x6b, 0xac, 0xb6, 0x93, 0x83, 0x98, 0x15, 0x9f, 0x82, 0x91, 0x3a, - 0x09, 0x48, 0x24, 0x23, 0x2b, 0x33, 0x6f, 0x55, 0x2d, 0x68, 0x65, 0xd8, 0xc0, 0x64, 0x93, 0x25, - 0x48, 0xa2, 0x1d, 0xae, 0xe7, 0x67, 0x2f, 0xae, 0xa8, 0x12, 0xac, 0x61, 0xa1, 0x29, 0xc3, 0xeb, - 0xc3, 0x03, 0x08, 0xc6, 0xf6, 0x71, 0xd2, 0x7c, 0x00, 0xc6, 0xcc, 0x04, 0x35, 0x42, 0xdb, 0x54, - 0x0e, 0x7f, 0x33, 0xaf, 0x0d, 0xce, 0x60, 0xd3, 0x85, 0x50, 0x8b, 0x76, 0x70, 0x27, 0x10, 0x6a, - 0xa7, 0x5a, 0x08, 0x73, 0x0c, 0x8a, 0x45, 0x29, 0xcb, 0xec, 0xc1, 0x36, 0x60, 0x0e, 0x17, 0xd9, - 0x41, 0xd2, 0xcc, 0x1e, 0x5a, 0x19, 0x36, 0x30, 0x29, 0x07, 0x61, 0x96, 0x05, 0x73, 0xa9, 0x65, - 0x6c, 0xa9, 0x6d, 0x18, 0x0b, 0x4d, 0x73, 0x12, 0xd7, 0xc1, 0xde, 0x73, 0xc0, 0xa9, 0x67, 0xd4, - 0xe5, 0x81, 0x1a, 0x19, 0xeb, 0x53, 0x86, 0x3e, 0xd5, 0xbb, 0xf5, 0x6b, 0x1b, 0x23, 0x66, 0x60, - 0x6e, 0xcf, 0x9b, 0x15, 0x6b, 0x70, 0xb6, 0x1d, 0xd6, 0xd6, 0x22, 0x3f, 0x8c, 0xfc, 0x64, 0x67, - 0xb6, 0xe9, 0xc5, 0x31, 0x9b, 0x18, 0xa3, 0xa6, 0x3e, 0xb6, 0x96, 0x83, 0x83, 0x73, 0x6b, 0xd2, - 0x03, 0x59, 0x5b, 0x00, 0x59, 0x78, 0x5c, 0x91, 0xef, 0x64, 0x12, 0x11, 0xab, 0x52, 0xf7, 0x0c, - 0x9c, 0xae, 0x74, 0xda, 0xed, 0xa6, 0x4f, 0x6a, 0xca, 0xab, 0xe2, 0x7e, 0x10, 0x4e, 0x89, 0x8c, - 0xbc, 0x4a, 0xfb, 0x39, 0x54, 0xfe, 0x78, 0xf7, 0xdd, 0x70, 0x2a, 0xb3, 0x95, 0xde, 0x21, 0xe2, - 0xc3, 0xfd, 0xaf, 0x7d, 0xbc, 0x8a, 0x16, 0x7c, 0x84, 0x5e, 0xc9, 0x6a, 0x39, 0x76, 0x72, 0xcb, - 0x6a, 0xfa, 0x8d, 0x48, 0x14, 0x9b, 0xa7, 0x31, 0x35, 0xe4, 0xdd, 0x03, 0x6b, 0x57, 0x84, 0x58, - 0x84, 0x3e, 0xdf, 0x87, 0x8c, 0x0b, 0x0c, 0x1f, 0x07, 0x50, 0x6c, 0x65, 0xfa, 0x02, 0xdb, 0xfd, - 0x64, 0x2b, 0x5e, 0x41, 0x62, 0xac, 0x71, 0x44, 0x01, 0x0c, 0xb2, 0x86, 0x10, 0x79, 0x81, 0xd5, - 0x5a, 0x5f, 0x99, 0x92, 0xb9, 0xc2, 0x69, 0x63, 0xc9, 0xc4, 0xfd, 0x5c, 0x01, 0xf2, 0x63, 0xe4, - 0xd0, 0xc7, 0xbb, 0x3f, 0xf8, 0x33, 0x16, 0x07, 0x42, 0x04, 0xe9, 0xf5, 0xfe, 0xe6, 0x81, 0xf9, - 0xcd, 0x57, 0x2c, 0x8d, 0x83, 0xe0, 0xdb, 0xf5, 0xe5, 0xdd, 0xff, 0xe5, 0x40, 0x69, 0x7d, 0x7d, - 0x59, 0x29, 0x03, 0x18, 0xce, 0xc7, 0x3c, 0x37, 0x04, 0x0b, 0x04, 0x98, 0x0d, 0x5b, 0x6d, 0x1e, - 0x17, 0x20, 0xe2, 0x15, 0x58, 0xfa, 0xe8, 0x4a, 0x2e, 0x06, 0xee, 0x51, 0x13, 0x2d, 0xc2, 0x19, - 0xbd, 0xa4, 0xa2, 0x3d, 0xe6, 0x59, 0x14, 0xa9, 0xa2, 0xba, 0x8b, 0x71, 0x5e, 0x9d, 0x2c, 0x29, - 0x61, 0xff, 0x66, 0x1b, 0x7a, 0x0e, 0x29, 0x51, 0x8c, 0xf3, 0xea, 0xb8, 0xab, 0x50, 0x5a, 0xf7, - 0x22, 0xd5, 0xf1, 0x0f, 0xc1, 0x78, 0x35, 0x6c, 0x49, 0x05, 0x67, 0x99, 0x6c, 0x93, 0xa6, 0xe8, - 0x32, 0x7f, 0x22, 0x27, 0x53, 0x86, 0xbb, 0xb0, 0xdd, 0xdf, 0x78, 0x10, 0xd4, 0x5d, 0xd7, 0x03, - 0xec, 0xc1, 0x6d, 0x15, 0x3d, 0x5c, 0xb4, 0x1c, 0x3d, 0xac, 0x76, 0xa3, 0x4c, 0x04, 0x71, 0x92, - 0x46, 0x10, 0x0f, 0xd8, 0x8e, 0x20, 0x56, 0x6a, 0x79, 0x57, 0x14, 0xf1, 0x57, 0x1c, 0x18, 0x09, - 0xc2, 0x1a, 0x51, 0x0e, 0xdb, 0x41, 0xb6, 0xc2, 0x5f, 0xb0, 0x77, 0x19, 0x83, 0x47, 0xc3, 0x0a, - 0xf2, 0x3c, 0xb2, 0x5d, 0x6d, 0xe2, 0x7a, 0x11, 0x36, 0xda, 0x81, 0xe6, 0x35, 0x4b, 0x38, 0x77, - 0x38, 0xdd, 0x9f, 0x77, 0xa2, 0xbc, 0xa3, 0x59, 0xfb, 0x96, 0xa6, 0x59, 0x0e, 0xdb, 0xb2, 0xf0, - 0xca, 0x7b, 0x89, 0x9a, 0xdf, 0x4c, 0x66, 0x40, 0x4f, 0x35, 0x4e, 0x17, 0x06, 0x78, 0x08, 0xbc, - 0x48, 0x4a, 0xc6, 0xdc, 0xb9, 0x3c, 0x3c, 0x1e, 0x8b, 0x12, 0x94, 0xc8, 0xa0, 0x90, 0x92, 0xad, - 0xf7, 0x4c, 0x8c, 0xa0, 0x93, 0xfc, 0xa8, 0x10, 0xf4, 0xb4, 0x6e, 0xa9, 0x18, 0x39, 0x88, 0xa5, - 0x62, 0xb4, 0xa7, 0x95, 0xe2, 0x0b, 0x0e, 0x8c, 0x54, 0xb5, 0xf7, 0x45, 0xca, 0x8f, 0xda, 0x7a, - 0x66, 0x3d, 0xef, 0x19, 0x18, 0xee, 0x25, 0x34, 0xde, 0x33, 0x31, 0xb8, 0xb3, 0x4c, 0xac, 0xcc, - 0x2c, 0xc3, 0x94, 0x23, 0x2b, 0x19, 0x4e, 0x4c, 0x33, 0x8f, 0x0c, 0xae, 0xa5, 0x30, 0x2c, 0x78, - 0xa1, 0x57, 0x61, 0x48, 0xde, 0xa2, 0x10, 0xb7, 0x0d, 0xb0, 0x0d, 0xb7, 0x8d, 0xe9, 0x1b, 0x96, - 0xe9, 0x1b, 0x39, 0x14, 0x2b, 0x8e, 0xa8, 0x01, 0x7d, 0x35, 0xaf, 0x2e, 0xee, 0x1d, 0xac, 0xd8, - 0x49, 0x8f, 0x2b, 0x79, 0xb2, 0x43, 0xec, 0xdc, 0xf4, 0x02, 0xa6, 0x2c, 0xd0, 0xad, 0xf4, 0x81, - 0x86, 0x71, 0x6b, 0xbb, 0xaf, 0xa9, 0x48, 0x72, 0x9d, 0xa0, 0xeb, 0xbd, 0x87, 0x9a, 0x70, 0xa7, - 0xff, 0x35, 0xc6, 0x76, 0xde, 0x4e, 0x7e, 0x5d, 0x9e, 0x31, 0x27, 0x75, 0xc9, 0x53, 0x2e, 0x8d, - 0x24, 0x69, 0x97, 0x7f, 0xde, 0x16, 0x17, 0x96, 0xf7, 0x85, 0xbf, 0x88, 0xbf, 0xbe, 0xbe, 0x86, - 0x19, 0x75, 0xd4, 0x84, 0x81, 0x36, 0x8b, 0xf4, 0x29, 0xbf, 0xd3, 0xd6, 0xde, 0xc2, 0x23, 0x87, - 0xf8, 0xdc, 0xe4, 0xff, 0x63, 0xc1, 0x03, 0x5d, 0x81, 0x41, 0xfe, 0xce, 0x10, 0xbf, 0xf7, 0x51, - 0xba, 0x3c, 0xd1, 0xfb, 0xb5, 0xa2, 0x74, 0xa3, 0xe0, 0xbf, 0x63, 0x2c, 0xeb, 0xa2, 0x2f, 0x3a, - 0x30, 0x46, 0x25, 0x6a, 0xfa, 0x30, 0x52, 0x19, 0xd9, 0x92, 0x59, 0xd7, 0x63, 0xaa, 0x91, 0x48, - 0x59, 0xa3, 0x0e, 0x92, 0x8b, 0x06, 0x3b, 0x9c, 0x61, 0x8f, 0x5e, 0x83, 0xa1, 0xd8, 0xaf, 0x91, - 0xaa, 0x17, 0xc5, 0xe5, 0x33, 0xc7, 0xd3, 0x94, 0xd4, 0x81, 0x27, 0x18, 0x61, 0xc5, 0x12, 0xfd, - 0x2a, 0x7b, 0xb8, 0xb6, 0xda, 0xf0, 0xb7, 0xc9, 0x72, 0x58, 0xe5, 0x07, 0x9f, 0xb3, 0xb6, 0xd6, - 0xbe, 0x74, 0x55, 0x4a, 0xca, 0xc2, 0xaf, 0x65, 0xb2, 0xc3, 0x59, 0xfe, 0xe8, 0xef, 0x38, 0x70, - 0x8e, 0xbf, 0x20, 0x91, 0x7d, 0x14, 0xe5, 0xdc, 0x11, 0x8d, 0x58, 0xec, 0xc2, 0xca, 0x74, 0x1e, - 0x49, 0x9c, 0xcf, 0x89, 0xe5, 0x7b, 0x36, 0xdf, 0xb1, 0x3a, 0x6f, 0xd5, 0x91, 0x7d, 0xf0, 0xb7, - 0xab, 0xd0, 0x13, 0x50, 0x6a, 0x8b, 0xed, 0xd0, 0x8f, 0x5b, 0xec, 0xfa, 0x51, 0x1f, 0xbf, 0x18, - 0xba, 0x96, 0x82, 0xb1, 0x8e, 0x63, 0x24, 0xff, 0x7e, 0x6c, 0xbf, 0xe4, 0xdf, 0xe8, 0x3a, 0x94, - 0x92, 0xb0, 0x29, 0xf2, 0xdf, 0xc6, 0xe5, 0x32, 0x9b, 0x81, 0x17, 0xf3, 0xd6, 0xd6, 0xba, 0x42, - 0x4b, 0xcf, 0xfa, 0x29, 0x2c, 0xc6, 0x3a, 0x1d, 0x16, 0xb0, 0x2d, 0x5e, 0xe6, 0x88, 0xd8, 0x21, - 0xff, 0xde, 0x4c, 0xc0, 0xb6, 0x5e, 0x88, 0x4d, 0x5c, 0xb4, 0x00, 0xa7, 0xdb, 0x5d, 0x56, 0x02, - 0x7e, 0xed, 0x51, 0xc5, 0xc8, 0x74, 0x9b, 0x08, 0xba, 0xeb, 0xf4, 0x48, 0x70, 0x7d, 0xff, 0x51, - 0x12, 0x5c, 0xa3, 0x1a, 0xdc, 0xef, 0x75, 0x92, 0x90, 0x65, 0x2c, 0x32, 0xab, 0xf0, 0x88, 0xf4, - 0x07, 0x79, 0x90, 0xfb, 0xde, 0xee, 0xe4, 0xfd, 0xd3, 0xfb, 0xe0, 0xe1, 0x7d, 0xa9, 0xa0, 0x97, - 0x61, 0x88, 0x88, 0x24, 0xdd, 0xe5, 0x9f, 0xb3, 0xb5, 0xf5, 0x9b, 0x69, 0xbf, 0x65, 0xb0, 0x2f, - 0x87, 0x61, 0xc5, 0x0f, 0xad, 0x43, 0xa9, 0x11, 0xc6, 0xc9, 0x74, 0xd3, 0xf7, 0x62, 0x12, 0x97, - 0x1f, 0x60, 0x53, 0x21, 0x57, 0xa3, 0xba, 0x2a, 0xd1, 0xd2, 0x99, 0x70, 0x35, 0xad, 0x89, 0x75, - 0x32, 0x88, 0x30, 0x27, 0x35, 0x0b, 0xc7, 0x97, 0x0e, 0xb8, 0x8b, 0xac, 0x63, 0x8f, 0xe4, 0x51, - 0x5e, 0x0b, 0x6b, 0x15, 0x13, 0x5b, 0x79, 0xa9, 0x75, 0x20, 0xce, 0xd2, 0x44, 0x4f, 0xc1, 0x48, - 0x3b, 0xac, 0x55, 0xda, 0xa4, 0xba, 0xe6, 0x25, 0xd5, 0x46, 0x79, 0xd2, 0xb4, 0x36, 0xae, 0x69, - 0x65, 0xd8, 0xc0, 0x44, 0x6d, 0x18, 0x6c, 0xf1, 0x0c, 0x15, 0xe5, 0x87, 0x6c, 0x9d, 0x58, 0x44, - 0xca, 0x0b, 0x61, 0x19, 0xe0, 0x3f, 0xb0, 0x64, 0x83, 0xfe, 0xb1, 0x03, 0xa7, 0x32, 0xd7, 0xe4, - 0xca, 0xef, 0xb0, 0xe9, 0xdb, 0xd1, 0x08, 0xcf, 0x3c, 0xc2, 0x86, 0xcf, 0x04, 0xde, 0xee, 0x06, - 0xe1, 0x6c, 0x8b, 0xf8, 0xb8, 0xb0, 0x34, 0x33, 0xe5, 0x87, 0xed, 0x8d, 0x0b, 0x23, 0x28, 0xc7, - 0x85, 0xfd, 0xc0, 0x92, 0x0d, 0x7a, 0x0c, 0x06, 0x45, 0xea, 0xc8, 0xf2, 0x23, 0xa6, 0xeb, 0x5f, - 0x64, 0x98, 0xc4, 0xb2, 0xbc, 0x2b, 0x75, 0xcc, 0xe3, 0xb6, 0x52, 0xc7, 0xa8, 0xf3, 0xde, 0xe1, - 0x53, 0xc7, 0x4c, 0x7c, 0x10, 0x4e, 0x77, 0x9d, 0x12, 0x0f, 0x95, 0xbb, 0xe5, 0x2e, 0x73, 0xbf, - 0xb8, 0xbf, 0xee, 0x80, 0x9e, 0x2c, 0xc0, 0xfa, 0x73, 0x3f, 0x4f, 0xc1, 0x48, 0x95, 0xbf, 0xbe, - 0xca, 0xd3, 0x0d, 0xf4, 0x9b, 0xc6, 0xec, 0x59, 0xad, 0x0c, 0x1b, 0x98, 0xee, 0x55, 0x40, 0xdd, - 0x6f, 0x31, 0x1c, 0xc9, 0x2b, 0xf4, 0x4f, 0x1d, 0x18, 0x35, 0xd4, 0x1b, 0xeb, 0x1e, 0xeb, 0x79, - 0x40, 0x2d, 0x3f, 0x8a, 0xc2, 0x48, 0x7f, 0xe6, 0x52, 0xa4, 0x04, 0x61, 0x91, 0x2c, 0x2b, 0x5d, - 0xa5, 0x38, 0xa7, 0x86, 0xfb, 0xcf, 0xfb, 0x21, 0x0d, 0xe1, 0x57, 0x99, 0xaa, 0x9d, 0x9e, 0x99, - 0xaa, 0x1f, 0x87, 0xa1, 0x17, 0xe3, 0x30, 0x58, 0x4b, 0xf3, 0x59, 0xab, 0x6f, 0xf1, 0x74, 0x65, - 0xf5, 0x1a, 0xc3, 0x54, 0x18, 0x0c, 0xfb, 0xa5, 0x79, 0xbf, 0x99, 0x74, 0x27, 0x3c, 0x7e, 0xfa, - 0x19, 0x0e, 0xc7, 0x0a, 0x83, 0xbd, 0x78, 0xb9, 0x4d, 0x94, 0x97, 0x23, 0x7d, 0xf1, 0x92, 0x3f, - 0xb3, 0xc2, 0xca, 0xd0, 0x25, 0x18, 0x56, 0x1e, 0x12, 0xe1, 0x76, 0x51, 0x23, 0xa5, 0xdc, 0x28, - 0x38, 0xc5, 0x61, 0xba, 0xab, 0xb0, 0xaa, 0x0b, 0x6b, 0x4f, 0xc5, 0xc6, 0x49, 0x2a, 0x63, 0xa7, - 0xe7, 0x1b, 0x96, 0x04, 0x63, 0xc5, 0x32, 0xcf, 0x6b, 0x3f, 0x7c, 0x2c, 0x5e, 0x7b, 0xed, 0x3e, - 0x49, 0xf1, 0xa0, 0xf7, 0x49, 0xcc, 0xb9, 0x3d, 0x74, 0xa0, 0xb9, 0xfd, 0x99, 0x3e, 0x18, 0x7c, - 0x96, 0x44, 0xec, 0xa9, 0x80, 0xc7, 0x60, 0x70, 0x9b, 0xff, 0x9b, 0xbd, 0x8c, 0x2c, 0x30, 0xb0, - 0x2c, 0xa7, 0xdf, 0x6d, 0xa3, 0xe3, 0x37, 0x6b, 0x73, 0xe9, 0x2a, 0x4e, 0x53, 0x79, 0xca, 0x02, - 0x9c, 0xe2, 0xd0, 0x0a, 0x75, 0x7a, 0x08, 0x69, 0xb5, 0xfc, 0x24, 0x1b, 0x84, 0xb7, 0x20, 0x0b, - 0x70, 0x8a, 0x83, 0x1e, 0x81, 0x81, 0xba, 0x9f, 0xac, 0x7b, 0xf5, 0xac, 0xdb, 0x77, 0x81, 0x41, - 0xb1, 0x28, 0x65, 0x3e, 0x3f, 0x3f, 0x59, 0x8f, 0x08, 0x33, 0x42, 0x77, 0x65, 0x53, 0x59, 0xd0, - 0xca, 0xb0, 0x81, 0xc9, 0x9a, 0x14, 0x8a, 0x9e, 0x89, 0x08, 0xe4, 0xb4, 0x49, 0xb2, 0x00, 0xa7, - 0x38, 0x74, 0xfe, 0x57, 0xc3, 0x56, 0xdb, 0x6f, 0x8a, 0xd8, 0x78, 0x6d, 0xfe, 0xcf, 0x0a, 0x38, - 0x56, 0x18, 0x14, 0x9b, 0x8a, 0x30, 0x2a, 0x7e, 0xb2, 0xaf, 0x0b, 0xae, 0x09, 0x38, 0x56, 0x18, - 0xee, 0xb3, 0x30, 0xca, 0x57, 0xf2, 0x6c, 0xd3, 0xf3, 0x5b, 0x0b, 0xb3, 0xe8, 0x4a, 0xd7, 0x7d, - 0x92, 0xc7, 0x72, 0xee, 0x93, 0x9c, 0x33, 0x2a, 0x75, 0xdf, 0x2b, 0x71, 0x7f, 0x58, 0x80, 0xa1, - 0x13, 0x7c, 0xa0, 0xf5, 0xc4, 0xdf, 0x1a, 0x47, 0xb7, 0x32, 0x8f, 0xb3, 0xae, 0xd9, 0xbc, 0x1e, - 0xb6, 0xef, 0xc3, 0xac, 0xff, 0xad, 0x00, 0xe7, 0x25, 0xaa, 0x3c, 0x76, 0x2e, 0xcc, 0xb2, 0x47, - 0xef, 0x8e, 0x7f, 0xa0, 0x23, 0x63, 0xa0, 0xd7, 0xec, 0x1d, 0x9c, 0x17, 0x66, 0x7b, 0x0e, 0xf5, - 0xcb, 0x99, 0xa1, 0xc6, 0x56, 0xb9, 0xee, 0x3f, 0xd8, 0x7f, 0xee, 0xc0, 0x44, 0xfe, 0x60, 0x9f, - 0xc0, 0x7b, 0xb8, 0xaf, 0x99, 0xef, 0xe1, 0xfe, 0x82, 0xbd, 0x29, 0x66, 0x76, 0xa5, 0xc7, 0xcb, - 0xb8, 0xff, 0xd3, 0x81, 0xb3, 0xb2, 0x02, 0xdb, 0x3d, 0x67, 0xfc, 0x80, 0x45, 0x26, 0x1d, 0xff, - 0x34, 0x7b, 0xd5, 0x98, 0x66, 0xcf, 0xdb, 0xeb, 0xb8, 0xde, 0x8f, 0x5e, 0x13, 0xce, 0xfd, 0x33, - 0x07, 0xca, 0x79, 0x15, 0x4e, 0xe0, 0x93, 0xbf, 0x62, 0x7e, 0xf2, 0x67, 0x8f, 0xa7, 0xe7, 0xbd, - 0x3f, 0x78, 0xb9, 0xd7, 0x40, 0xa1, 0xa6, 0xd4, 0xab, 0x1c, 0x5b, 0xee, 0x73, 0xce, 0x22, 0x5f, - 0x41, 0x6b, 0xc2, 0x40, 0xcc, 0x42, 0x70, 0xc4, 0x14, 0xb8, 0x6a, 0x43, 0xdb, 0xa2, 0xf4, 0x84, - 0x3b, 0x80, 0xfd, 0x8f, 0x05, 0x0f, 0xf7, 0x37, 0x0b, 0x70, 0x41, 0xbd, 0x73, 0x4d, 0xb6, 0x49, - 0x33, 0x5d, 0x1f, 0xec, 0x55, 0x14, 0x4f, 0xfd, 0xb4, 0xf7, 0x2a, 0x4a, 0xca, 0x22, 0x5d, 0x0b, - 0x29, 0x0c, 0x6b, 0x3c, 0x51, 0x05, 0xce, 0xb1, 0x57, 0x4c, 0xe6, 0xfd, 0xc0, 0x6b, 0xfa, 0x2f, - 0x93, 0x08, 0x93, 0x56, 0xb8, 0xed, 0x35, 0x85, 0xa6, 0xae, 0xee, 0xa3, 0xcf, 0xe7, 0x21, 0xe1, - 0xfc, 0xba, 0x5d, 0x66, 0x84, 0xbe, 0x83, 0x9a, 0x11, 0xdc, 0x3f, 0x76, 0x60, 0xe4, 0x04, 0x5f, - 0x05, 0x0f, 0xcd, 0x25, 0xf1, 0xb4, 0xbd, 0x25, 0xd1, 0x63, 0x19, 0xec, 0x16, 0xa1, 0xeb, 0xa1, - 0x64, 0xf4, 0x59, 0x47, 0x05, 0x29, 0xf1, 0x60, 0xd0, 0x8f, 0xd8, 0x6b, 0xc7, 0x61, 0xb2, 0xa6, - 0xa2, 0xaf, 0x67, 0xec, 0x01, 0x05, 0x5b, 0x09, 0xce, 0xba, 0x5a, 0x73, 0x84, 0x94, 0xb2, 0x5f, - 0x71, 0x00, 0x78, 0x3b, 0x45, 0xca, 0x7a, 0xda, 0xb6, 0x8d, 0x63, 0x1b, 0x29, 0xca, 0x84, 0x37, - 0x4d, 0x2d, 0xa1, 0xb4, 0x00, 0x6b, 0x2d, 0xb9, 0x8b, 0x5c, 0xb1, 0x77, 0x9d, 0xa6, 0xf6, 0x8b, - 0x0e, 0x9c, 0xca, 0x34, 0x37, 0xa7, 0xfe, 0xa6, 0xf9, 0xae, 0xa7, 0x05, 0xcd, 0xca, 0x4c, 0x64, - 0xae, 0x1b, 0x4f, 0xfe, 0xa5, 0x0b, 0xc6, 0x0b, 0xf3, 0xe8, 0x15, 0x18, 0x96, 0x96, 0x0f, 0x39, - 0xbd, 0x6d, 0xbe, 0x6f, 0xac, 0x8e, 0x37, 0x12, 0x12, 0xe3, 0x94, 0x5f, 0x26, 0x06, 0xb2, 0x70, - 0xa0, 0x18, 0xc8, 0xb7, 0xf7, 0x75, 0xe4, 0x7c, 0x63, 0x7b, 0xff, 0xb1, 0x18, 0xdb, 0xef, 0xb7, - 0x6e, 0x6c, 0x7f, 0xe0, 0x84, 0x8d, 0xed, 0x9a, 0x3f, 0xb3, 0x78, 0x17, 0xfe, 0xcc, 0x57, 0xe0, - 0xec, 0x76, 0x7a, 0xe8, 0x54, 0x33, 0x49, 0x24, 0xc5, 0x7a, 0x2c, 0xd7, 0xc4, 0x4e, 0x0f, 0xd0, - 0x71, 0x42, 0x82, 0x44, 0x3b, 0xae, 0xa6, 0xe1, 0x97, 0xcf, 0xe6, 0x90, 0xc3, 0xb9, 0x4c, 0xb2, - 0x8e, 0xa9, 0xc1, 0x03, 0x38, 0xa6, 0xbe, 0xe3, 0xc0, 0x39, 0xaf, 0xeb, 0x02, 0x23, 0x26, 0x9b, - 0x22, 0x3a, 0xe6, 0x86, 0x3d, 0x15, 0xc2, 0x20, 0x2f, 0x3c, 0x80, 0x79, 0x45, 0x38, 0xbf, 0x41, - 0xe8, 0xe1, 0x34, 0x4a, 0x80, 0x07, 0xed, 0xe6, 0xbb, 0xf4, 0xbf, 0x9e, 0x0d, 0x3d, 0x02, 0x36, - 0xf4, 0x1f, 0xb3, 0x7b, 0xda, 0xb6, 0x10, 0x7e, 0x54, 0xba, 0x8b, 0xf0, 0xa3, 0x8c, 0x97, 0x70, - 0xc4, 0x92, 0x97, 0x30, 0x80, 0x71, 0xbf, 0xe5, 0xd5, 0xc9, 0x5a, 0xa7, 0xd9, 0xe4, 0x37, 0x92, - 0xe4, 0x0b, 0xd4, 0xb9, 0x16, 0xbc, 0xe5, 0xb0, 0xea, 0x35, 0x45, 0xce, 0x0f, 0x15, 0xb0, 0xac, - 0x6e, 0x5e, 0x2d, 0x66, 0x28, 0xe1, 0x2e, 0xda, 0x74, 0xc2, 0xb2, 0xfc, 0x8e, 0x24, 0xa1, 0xa3, - 0xcd, 0x62, 0x5c, 0x86, 0xf8, 0x84, 0xbd, 0x9a, 0x82, 0xb1, 0x8e, 0x83, 0x96, 0x60, 0xb8, 0x16, - 0xc4, 0xe2, 0x2e, 0xf6, 0x29, 0x26, 0xcc, 0xde, 0x45, 0x45, 0xe0, 0xdc, 0xb5, 0x8a, 0xba, 0x85, - 0x7d, 0x7f, 0x4e, 0xc2, 0x52, 0x55, 0x8e, 0xd3, 0xfa, 0x68, 0x85, 0x11, 0x13, 0x6f, 0xeb, 0xf1, - 0xd0, 0x93, 0x07, 0x7b, 0x78, 0xc1, 0xe6, 0xae, 0xc9, 0xd7, 0x01, 0x47, 0x05, 0x3b, 0xf1, 0x48, - 0x5e, 0x4a, 0x41, 0x7b, 0x09, 0xfc, 0xf4, 0xbe, 0x2f, 0x81, 0xb3, 0x4c, 0xc5, 0x49, 0x53, 0x79, - 0xb2, 0x2f, 0x5a, 0xcb, 0x54, 0x9c, 0x06, 0x75, 0x8a, 0x4c, 0xc5, 0x29, 0x00, 0xeb, 0x2c, 0xd1, - 0x6a, 0x2f, 0x8f, 0xfe, 0x19, 0x26, 0x34, 0x0e, 0xef, 0x9f, 0xd7, 0x43, 0xbf, 0xcf, 0xee, 0x17, - 0xfa, 0xdd, 0xed, 0x8a, 0x3e, 0x77, 0x08, 0x57, 0x74, 0x83, 0xe5, 0x90, 0x5d, 0x98, 0x15, 0xde, - 0x7f, 0x0b, 0xe7, 0x3b, 0x96, 0x73, 0x86, 0x07, 0xc9, 0xb2, 0x7f, 0x31, 0x67, 0xd0, 0x33, 0x3a, - 0xfe, 0xc2, 0x91, 0xa3, 0xe3, 0x33, 0xfe, 0xdc, 0x7b, 0x8f, 0xcd, 0x9f, 0x3b, 0x71, 0x02, 0xfe, - 0xdc, 0xfb, 0x0e, 0xec, 0xcf, 0xbd, 0x05, 0x67, 0xda, 0x61, 0x6d, 0xce, 0x8f, 0xa3, 0x0e, 0xbb, - 0x6f, 0x39, 0xd3, 0xa9, 0xd5, 0x49, 0xc2, 0x1c, 0xc2, 0xa5, 0xcb, 0xef, 0xd2, 0x1b, 0xd9, 0x66, - 0xab, 0x52, 0x2e, 0xb8, 0x4c, 0x05, 0x66, 0x07, 0x61, 0xd1, 0xbe, 0x39, 0x85, 0x38, 0x8f, 0x85, - 0xee, 0x49, 0x7e, 0xf0, 0x64, 0x3c, 0xc9, 0x1f, 0x82, 0xa1, 0xb8, 0xd1, 0x49, 0x6a, 0xe1, 0xcd, - 0x80, 0x85, 0x0b, 0x0c, 0xcf, 0xbc, 0x43, 0xd9, 0xa5, 0x05, 0xfc, 0xf6, 0xee, 0xe4, 0xb8, 0xfc, - 0x5f, 0x33, 0x49, 0x0b, 0x08, 0xfa, 0x46, 0x8f, 0x9b, 0x55, 0xee, 0x71, 0xde, 0xac, 0xba, 0x70, - 0xa8, 0x5b, 0x55, 0x79, 0xee, 0xf2, 0x87, 0x7e, 0xe6, 0xdc, 0xe5, 0x5f, 0x73, 0x60, 0x74, 0x5b, - 0xb7, 0xff, 0x0b, 0x97, 0xbe, 0x85, 0x80, 0x21, 0xc3, 0xad, 0x30, 0xe3, 0x52, 0xa1, 0x65, 0x80, - 0x6e, 0x67, 0x01, 0xd8, 0x6c, 0x49, 0x4e, 0x30, 0xd3, 0xc3, 0x6f, 0x57, 0x30, 0xd3, 0x6b, 0x50, - 0x6a, 0x87, 0x35, 0x79, 0x62, 0x65, 0x7e, 0x7e, 0xbb, 0xb1, 0xcc, 0x5c, 0xff, 0x4c, 0x59, 0x60, - 0x9d, 0x1f, 0xfa, 0x82, 0x03, 0xe3, 0xf2, 0x90, 0x25, 0xfc, 0x77, 0xb1, 0x88, 0xc6, 0xb4, 0x79, - 0xb6, 0xe3, 0x49, 0x8d, 0x33, 0x7c, 0x70, 0x17, 0x67, 0xaa, 0x90, 0xa8, 0xe0, 0xb7, 0x7a, 0xcc, - 0x82, 0x8e, 0x85, 0x42, 0x32, 0x9d, 0x82, 0xb1, 0x8e, 0x83, 0xbe, 0xe9, 0x40, 0xb1, 0x11, 0x86, - 0x5b, 0x71, 0xf9, 0x31, 0x26, 0xd0, 0x9f, 0xb3, 0xac, 0x68, 0x5e, 0xa5, 0xb4, 0xb9, 0x86, 0xf9, - 0x84, 0x34, 0x04, 0x31, 0xd8, 0xed, 0xdd, 0xc9, 0x31, 0xe3, 0x3d, 0xae, 0xf8, 0xf5, 0xb7, 0x34, - 0x88, 0x30, 0x54, 0xb2, 0xa6, 0xa1, 0x37, 0x1d, 0x18, 0xbf, 0x99, 0xb1, 0x4e, 0x88, 0x70, 0x54, - 0x6c, 0xdf, 0xee, 0xc1, 0x87, 0x3b, 0x0b, 0xc5, 0x5d, 0x2d, 0x40, 0x9f, 0x37, 0xad, 0x96, 0x3c, - 0x6e, 0xd5, 0xe2, 0x00, 0x66, 0xac, 0xa4, 0xfc, 0x3a, 0x52, 0xbe, 0xf9, 0xf2, 0xee, 0x83, 0x45, - 0x68, 0x67, 0xd2, 0x8f, 0x95, 0x53, 0x95, 0x98, 0xc6, 0x13, 0x0b, 0x8b, 0xdd, 0xf8, 0xfc, 0xba, - 0xed, 0xe4, 0xcd, 0xf3, 0x30, 0x66, 0x3a, 0xea, 0xd0, 0x7b, 0xcc, 0x37, 0x51, 0x2e, 0x66, 0x9f, - 0x97, 0x18, 0x95, 0xf8, 0xc6, 0x13, 0x13, 0xc6, 0x1b, 0x10, 0x85, 0x63, 0x7d, 0x03, 0xa2, 0xef, - 0x64, 0xde, 0x80, 0x18, 0x3f, 0x8e, 0x37, 0x20, 0x4e, 0x1f, 0xea, 0x0d, 0x08, 0xed, 0x0d, 0x8e, - 0xfe, 0x3b, 0xbc, 0xc1, 0x31, 0x0d, 0xa7, 0xe4, 0x9d, 0x23, 0x22, 0xd2, 0xec, 0x73, 0x1f, 0xbe, - 0x7a, 0x26, 0x7e, 0xd6, 0x2c, 0xc6, 0x59, 0x7c, 0xba, 0xc8, 0x8a, 0x01, 0xab, 0x39, 0x60, 0x2b, - 0x28, 0xcb, 0x9c, 0x5a, 0xec, 0x2c, 0x2c, 0x44, 0x94, 0x8c, 0xb2, 0x2e, 0x32, 0xd8, 0x6d, 0xf9, - 0x0f, 0xe6, 0x2d, 0x40, 0x2f, 0x40, 0x39, 0xdc, 0xdc, 0x6c, 0x86, 0x5e, 0x2d, 0x7d, 0xa8, 0x42, - 0x06, 0x19, 0xf0, 0x5b, 0xb5, 0x2a, 0x2b, 0xf1, 0x6a, 0x0f, 0x3c, 0xdc, 0x93, 0x02, 0xfa, 0x0e, - 0x55, 0x4c, 0x92, 0x30, 0x22, 0xb5, 0xd4, 0xf0, 0x32, 0xcc, 0xfa, 0x4c, 0xac, 0xf7, 0xb9, 0x62, - 0xf2, 0xe1, 0xbd, 0x57, 0x1f, 0x25, 0x53, 0x8a, 0xb3, 0xcd, 0x42, 0x11, 0x9c, 0x6f, 0xe7, 0xd9, - 0x7d, 0x62, 0x71, 0x53, 0x6a, 0x3f, 0xeb, 0x93, 0x7a, 0x0c, 0x3d, 0xd7, 0x72, 0x14, 0xe3, 0x1e, - 0x94, 0xf5, 0xc7, 0x24, 0x86, 0x4e, 0xe6, 0x31, 0x89, 0x4f, 0x00, 0x54, 0x65, 0x52, 0x3a, 0x69, - 0x49, 0x58, 0xb2, 0x72, 0x85, 0x87, 0xd3, 0xd4, 0xde, 0x05, 0x56, 0x6c, 0xb0, 0xc6, 0x12, 0xfd, - 0xdf, 0xdc, 0xd7, 0x56, 0xb8, 0xb9, 0xa4, 0x6e, 0x7d, 0x4e, 0xfc, 0xcc, 0xbd, 0xb8, 0xf2, 0x4f, - 0x1c, 0x98, 0xe0, 0x33, 0x2f, 0xab, 0xdc, 0x53, 0xd5, 0x42, 0xdc, 0x29, 0xb2, 0x1d, 0x87, 0xc2, - 0x93, 0x4b, 0x19, 0x5c, 0x99, 0xd7, 0x7a, 0x9f, 0x96, 0xa0, 0xaf, 0xe4, 0x1c, 0x29, 0x4e, 0xd9, - 0x32, 0x40, 0xe6, 0xbf, 0x99, 0x71, 0x66, 0xef, 0x20, 0xa7, 0x88, 0x7f, 0xd6, 0xd3, 0x3e, 0x8a, - 0x58, 0xf3, 0x7e, 0xf1, 0x98, 0xec, 0xa3, 0xfa, 0xc3, 0x1e, 0x87, 0xb2, 0x92, 0x7e, 0xd1, 0x81, - 0x71, 0x2f, 0x13, 0x37, 0xc2, 0x8c, 0x3a, 0x56, 0x0c, 0x4c, 0xd3, 0x51, 0x1a, 0x8c, 0xc2, 0x94, - 0xbc, 0x6c, 0x88, 0x0a, 0xee, 0x62, 0x8e, 0x7e, 0xe8, 0xc0, 0x7d, 0xe9, 0xeb, 0x21, 0x71, 0x7a, - 0x47, 0x58, 0x34, 0xee, 0x2c, 0x5b, 0x8d, 0x2f, 0x59, 0x5f, 0x8d, 0xeb, 0xbd, 0x79, 0xf2, 0x75, - 0xf9, 0x90, 0x58, 0x97, 0xf7, 0xed, 0x83, 0x89, 0xf7, 0x6b, 0xfa, 0xc4, 0x67, 0x1d, 0xfe, 0xbc, - 0x5a, 0x4f, 0x95, 0x6f, 0xc3, 0x54, 0xf9, 0x96, 0x6d, 0x3e, 0xf0, 0xa4, 0xeb, 0x9e, 0xbf, 0xe2, - 0xc0, 0xd9, 0xbc, 0x1d, 0x29, 0xa7, 0x49, 0x1f, 0x33, 0x9b, 0x64, 0xf1, 0x94, 0xa5, 0x37, 0xc8, - 0xca, 0xeb, 0x30, 0x13, 0xd7, 0xe0, 0xc1, 0x3b, 0x7d, 0xc5, 0x3b, 0xd1, 0x1b, 0xd2, 0xd5, 0xe2, - 0x3f, 0x1b, 0xd6, 0x5c, 0x8a, 0x09, 0x69, 0x5b, 0x0f, 0xc8, 0x0e, 0x60, 0xc0, 0x0f, 0x9a, 0x7e, - 0x40, 0xc4, 0x3d, 0x51, 0x9b, 0x67, 0x58, 0xf1, 0x3e, 0x14, 0xa5, 0x8e, 0x05, 0x97, 0xb7, 0xd9, - 0xc3, 0x98, 0x7d, 0x71, 0xaf, 0xff, 0xe4, 0x5f, 0xdc, 0xbb, 0x09, 0xc3, 0x37, 0xfd, 0xa4, 0xc1, - 0x22, 0x23, 0x84, 0xe3, 0xce, 0xc2, 0xfd, 0x4a, 0x4a, 0x2e, 0xed, 0xfb, 0x0d, 0xc9, 0x00, 0xa7, - 0xbc, 0xd0, 0x25, 0xce, 0x98, 0x85, 0x61, 0x67, 0xe3, 0x63, 0x6f, 0xc8, 0x02, 0x9c, 0xe2, 0xd0, - 0xc1, 0x1a, 0xa1, 0xbf, 0x64, 0xb6, 0x2a, 0x91, 0x40, 0xda, 0x46, 0x62, 0x50, 0x41, 0x91, 0xdf, - 0x62, 0xbe, 0xa1, 0xf1, 0xc0, 0x06, 0x47, 0x95, 0xc3, 0x7b, 0xa8, 0x67, 0x0e, 0xef, 0x57, 0x99, - 0xc2, 0x96, 0xf8, 0x41, 0x87, 0xac, 0x06, 0x22, 0x78, 0x7b, 0xd9, 0xce, 0x9d, 0x6b, 0x4e, 0x93, - 0x1f, 0xc1, 0xd3, 0xdf, 0x58, 0xe3, 0xa7, 0xf9, 0x4f, 0x4a, 0xfb, 0xfa, 0x4f, 0x52, 0x93, 0xcb, - 0x88, 0x75, 0x93, 0x4b, 0x42, 0xda, 0x56, 0x4c, 0x2e, 0x3f, 0x53, 0xe6, 0x80, 0x3f, 0x77, 0x00, - 0x29, 0xbd, 0x4b, 0x09, 0xd4, 0x13, 0x88, 0x90, 0xfc, 0xa4, 0x03, 0x10, 0xa8, 0x77, 0x59, 0xed, - 0xee, 0x82, 0x9c, 0x66, 0xda, 0x80, 0x14, 0x86, 0x35, 0x9e, 0xee, 0x9f, 0x3a, 0x69, 0x20, 0x72, - 0xda, 0xf7, 0x13, 0x88, 0x08, 0xdb, 0x31, 0x23, 0xc2, 0xd6, 0x2d, 0x9a, 0xee, 0x55, 0x37, 0x7a, - 0xc4, 0x86, 0xfd, 0xa4, 0x00, 0xa7, 0x74, 0xe4, 0x0a, 0x39, 0x89, 0x8f, 0x7d, 0xd3, 0x08, 0x87, - 0xbd, 0x6e, 0xb7, 0xbf, 0x15, 0xe1, 0x01, 0xca, 0x0b, 0xbd, 0xfe, 0x44, 0x26, 0xf4, 0xfa, 0x86, - 0x7d, 0xd6, 0xfb, 0xc7, 0x5f, 0xff, 0x77, 0x07, 0xce, 0x64, 0x6a, 0x9c, 0xc0, 0x04, 0xdb, 0x36, - 0x27, 0xd8, 0x33, 0xd6, 0x7b, 0xdd, 0x63, 0x76, 0x7d, 0xab, 0xd0, 0xd5, 0x5b, 0x76, 0x88, 0xfb, - 0x8c, 0x03, 0x45, 0xaa, 0x2d, 0xcb, 0xe0, 0xac, 0x8f, 0x1d, 0xcb, 0x0c, 0x60, 0x7a, 0xbd, 0x90, - 0xce, 0xaa, 0x7d, 0x0c, 0x86, 0x39, 0xf7, 0x89, 0x4f, 0x3b, 0x00, 0x29, 0xd2, 0xdb, 0xa5, 0x02, - 0xbb, 0xdf, 0x2d, 0xc0, 0xb9, 0xdc, 0x69, 0x84, 0x3e, 0xa7, 0x2c, 0x72, 0x8e, 0xed, 0xd0, 0x43, - 0x83, 0x91, 0x6e, 0x98, 0x1b, 0x35, 0x0c, 0x73, 0xc2, 0x1e, 0xf7, 0x76, 0x1d, 0x60, 0x84, 0x98, - 0xd6, 0x06, 0xeb, 0xc7, 0x4e, 0x1a, 0xcd, 0xaa, 0xf2, 0x29, 0xfd, 0x25, 0xbc, 0x91, 0xe3, 0xfe, - 0x44, 0xbb, 0xae, 0x20, 0x3b, 0x7a, 0x02, 0xb2, 0xe2, 0xa6, 0x29, 0x2b, 0xb0, 0x7d, 0x3f, 0x72, - 0x0f, 0x61, 0xf1, 0x12, 0xe4, 0x39, 0x96, 0x0f, 0x96, 0xae, 0xd2, 0xb8, 0xdb, 0x5a, 0x38, 0xf0, - 0xdd, 0xd6, 0x51, 0x28, 0x3d, 0xef, 0xab, 0x54, 0xa7, 0x33, 0x53, 0xdf, 0xfb, 0xd1, 0xc5, 0x7b, - 0xbe, 0xff, 0xa3, 0x8b, 0xf7, 0xfc, 0xf0, 0x47, 0x17, 0xef, 0xf9, 0xe4, 0xde, 0x45, 0xe7, 0x7b, - 0x7b, 0x17, 0x9d, 0xef, 0xef, 0x5d, 0x74, 0x7e, 0xb8, 0x77, 0xd1, 0xf9, 0x4f, 0x7b, 0x17, 0x9d, - 0xbf, 0xf7, 0x27, 0x17, 0xef, 0x79, 0x7e, 0x48, 0x76, 0xec, 0x2f, 0x02, 0x00, 0x00, 0xff, 0xff, - 0xdc, 0x36, 0x17, 0xe9, 0xb5, 0xda, 0x00, 0x00, + 0x8a, 0x0c, 0x69, 0x53, 0x38, 0xf3, 0x28, 0x39, 0x8c, 0x94, 0x48, 0xc2, 0xc7, 0x01, 0x77, 0x04, + 0x70, 0x00, 0x7b, 0x71, 0x3c, 0x93, 0xa2, 0x25, 0x0d, 0x76, 0x1b, 0xbb, 0x43, 0xec, 0xce, 0x2c, + 0x67, 0x66, 0x71, 0x07, 0x7e, 0x49, 0xa1, 0xbe, 0xa8, 0x58, 0xb6, 0x62, 0x99, 0x92, 0x25, 0x39, + 0x49, 0x29, 0x8a, 0x94, 0xa8, 0xe4, 0x54, 0x52, 0xf6, 0xaf, 0xc4, 0xfe, 0x93, 0xca, 0x0f, 0x97, + 0x52, 0x4e, 0x25, 0x72, 0x45, 0x29, 0xeb, 0x47, 0x0c, 0x46, 0x70, 0xa2, 0x4a, 0x25, 0xa5, 0x1f, + 0x56, 0xc5, 0x49, 0x7c, 0xf9, 0xa8, 0x54, 0x7f, 0x4e, 0xf7, 0xec, 0x2c, 0x6e, 0x81, 0x6b, 0x1c, + 0x55, 0xf6, 0x2f, 0x60, 0x5f, 0xbf, 0x7e, 0xaf, 0xbb, 0xa7, 0xfb, 0xf5, 0xeb, 0xf7, 0x5e, 0xbf, + 0x86, 0xf5, 0xba, 0x9f, 0x34, 0x3a, 0x9b, 0x33, 0xd5, 0xb0, 0x75, 0xc1, 0x8b, 0xea, 0x61, 0x3b, + 0x0a, 0x5f, 0x64, 0xff, 0xbc, 0xfb, 0x46, 0x18, 0x6d, 0x6f, 0x35, 0xc3, 0x1b, 0xf1, 0x85, 0x9d, + 0x27, 0x2f, 0xb4, 0xb7, 0xeb, 0x17, 0xbc, 0xb6, 0x1f, 0x5f, 0x90, 0xd0, 0x0b, 0x3b, 0x4f, 0x78, + 0xcd, 0x76, 0xc3, 0x7b, 0xe2, 0x42, 0x9d, 0x04, 0x24, 0xf2, 0x12, 0x52, 0x9b, 0x69, 0x47, 0x61, + 0x12, 0xa2, 0x0f, 0xa5, 0x14, 0x67, 0x24, 0x45, 0xf6, 0xcf, 0x47, 0x15, 0xc5, 0x99, 0x9d, 0x27, + 0x67, 0xda, 0xdb, 0xf5, 0x19, 0x4a, 0x71, 0x46, 0x42, 0x67, 0x24, 0xc5, 0xa9, 0x77, 0x6b, 0x6d, + 0xaa, 0x87, 0xf5, 0xf0, 0x02, 0x23, 0xbc, 0xd9, 0xd9, 0x62, 0xbf, 0xd8, 0x0f, 0xf6, 0x1f, 0x67, + 0x38, 0xe5, 0x6e, 0x3f, 0x15, 0xcf, 0xf8, 0x21, 0x6d, 0xdf, 0x85, 0x6a, 0x18, 0x91, 0x0b, 0x3b, + 0x5d, 0x8d, 0x9a, 0x7a, 0x97, 0x86, 0xd3, 0x0e, 0x9b, 0x7e, 0x75, 0x37, 0x0f, 0xeb, 0x3d, 0x29, + 0x56, 0xcb, 0xab, 0x36, 0xfc, 0x80, 0x44, 0xbb, 0x69, 0xd7, 0x5b, 0x24, 0xf1, 0xf2, 0x6a, 0x5d, + 0xe8, 0x55, 0x2b, 0xea, 0x04, 0x89, 0xdf, 0x22, 0x5d, 0x15, 0x7e, 0xe1, 0x76, 0x15, 0xe2, 0x6a, + 0x83, 0xb4, 0xbc, 0xae, 0x7a, 0x4f, 0xf6, 0xaa, 0xd7, 0x49, 0xfc, 0xe6, 0x05, 0x3f, 0x48, 0xe2, + 0x24, 0xca, 0x56, 0x72, 0x2f, 0xc1, 0xd0, 0x6c, 0x2b, 0xec, 0x04, 0x09, 0x7a, 0x3f, 0x14, 0x77, + 0xbc, 0x66, 0x87, 0x94, 0x9d, 0x07, 0x9d, 0x47, 0x47, 0xe7, 0x1e, 0xfe, 0xee, 0xde, 0xf4, 0x3d, + 0xfb, 0x7b, 0xd3, 0xc5, 0x67, 0x29, 0xf0, 0xd6, 0xde, 0xf4, 0x69, 0x12, 0x54, 0xc3, 0x9a, 0x1f, + 0xd4, 0x2f, 0xbc, 0x18, 0x87, 0xc1, 0xcc, 0xd5, 0x4e, 0x6b, 0x93, 0x44, 0x98, 0xd7, 0x71, 0xff, + 0x5d, 0x01, 0x4e, 0xcc, 0x46, 0xd5, 0x86, 0xbf, 0x43, 0x2a, 0x09, 0xa5, 0x5f, 0xdf, 0x45, 0x0d, + 0x18, 0x48, 0xbc, 0x88, 0x91, 0x2b, 0x5d, 0x5c, 0x9d, 0xb9, 0xd3, 0xef, 0x3e, 0xb3, 0xe1, 0x45, + 0x92, 0xf6, 0xdc, 0xf0, 0xfe, 0xde, 0xf4, 0xc0, 0x86, 0x17, 0x61, 0xca, 0x02, 0x35, 0x61, 0x30, + 0x08, 0x03, 0x52, 0x2e, 0x30, 0x56, 0x57, 0xef, 0x9c, 0xd5, 0xd5, 0x30, 0x50, 0xfd, 0x98, 0x1b, + 0xd9, 0xdf, 0x9b, 0x1e, 0xa4, 0x10, 0xcc, 0xb8, 0xd0, 0x7e, 0xbd, 0xec, 0xb7, 0xcb, 0x03, 0xb6, + 0xfa, 0xf5, 0xbc, 0xdf, 0x36, 0xfb, 0xf5, 0xbc, 0xdf, 0xc6, 0x94, 0x85, 0xfb, 0xb9, 0x02, 0x8c, + 0xce, 0x46, 0xf5, 0x4e, 0x8b, 0x04, 0x49, 0x8c, 0x3e, 0x0e, 0xd0, 0xf6, 0x22, 0xaf, 0x45, 0x12, + 0x12, 0xc5, 0x65, 0xe7, 0xc1, 0x81, 0x47, 0x4b, 0x17, 0x97, 0xef, 0x9c, 0xfd, 0xba, 0xa4, 0x39, + 0x87, 0xc4, 0x27, 0x07, 0x05, 0x8a, 0xb1, 0xc6, 0x12, 0xbd, 0x02, 0xa3, 0x5e, 0x94, 0xf8, 0x5b, + 0x5e, 0x35, 0x89, 0xcb, 0x05, 0xc6, 0xff, 0xe9, 0x3b, 0xe7, 0x3f, 0x2b, 0x48, 0xce, 0x9d, 0x14, + 0xec, 0x47, 0x25, 0x24, 0xc6, 0x29, 0x3f, 0xf7, 0x77, 0x07, 0xa1, 0x34, 0x1b, 0x25, 0x4b, 0xf3, + 0x95, 0xc4, 0x4b, 0x3a, 0x31, 0xfa, 0x03, 0x07, 0x4e, 0xc5, 0x7c, 0xd8, 0x7c, 0x12, 0xaf, 0x47, + 0x61, 0x95, 0xc4, 0x31, 0xa9, 0x89, 0x71, 0xd9, 0xb2, 0xd2, 0x2e, 0xc9, 0x6c, 0xa6, 0xd2, 0xcd, + 0xe8, 0x52, 0x90, 0x44, 0xbb, 0x73, 0x4f, 0x88, 0x36, 0x9f, 0xca, 0xc1, 0x78, 0xe3, 0xed, 0x69, + 0x24, 0xbb, 0x42, 0x29, 0xf1, 0x4f, 0x8c, 0xf3, 0x5a, 0x8d, 0xbe, 0xea, 0xc0, 0x58, 0x3b, 0xac, + 0xc5, 0x98, 0x54, 0xc3, 0x4e, 0x9b, 0xd4, 0xc4, 0xf0, 0x7e, 0xd4, 0x6e, 0x37, 0xd6, 0x35, 0x0e, + 0xbc, 0xfd, 0xa7, 0x45, 0xfb, 0xc7, 0xf4, 0x22, 0x6c, 0x34, 0x05, 0x3d, 0x05, 0x63, 0x41, 0x98, + 0x54, 0xda, 0xa4, 0xea, 0x6f, 0xf9, 0xa4, 0xc6, 0x26, 0xfe, 0x48, 0x5a, 0xf3, 0xaa, 0x56, 0x86, + 0x0d, 0xcc, 0xa9, 0x45, 0x28, 0xf7, 0x1a, 0x39, 0x34, 0x09, 0x03, 0xdb, 0x64, 0x97, 0x0b, 0x1b, + 0x4c, 0xff, 0x45, 0xa7, 0xa5, 0x00, 0xa2, 0xcb, 0x78, 0x44, 0x48, 0x96, 0xf7, 0x15, 0x9e, 0x72, + 0xa6, 0x3e, 0x08, 0x27, 0xbb, 0x9a, 0x7e, 0x18, 0x02, 0xee, 0xf7, 0x86, 0x60, 0x44, 0x7e, 0x0a, + 0xf4, 0x20, 0x0c, 0x06, 0x5e, 0x4b, 0xca, 0xb9, 0x31, 0xd1, 0x8f, 0xc1, 0xab, 0x5e, 0x8b, 0xae, + 0x70, 0xaf, 0x45, 0x28, 0x46, 0xdb, 0x4b, 0x1a, 0x8c, 0x8e, 0x86, 0xb1, 0xee, 0x25, 0x0d, 0xcc, + 0x4a, 0xd0, 0xfd, 0x30, 0xd8, 0x0a, 0x6b, 0x84, 0x8d, 0x45, 0x91, 0x4b, 0x88, 0xd5, 0xb0, 0x46, + 0x30, 0x83, 0xd2, 0xfa, 0x5b, 0x51, 0xd8, 0x2a, 0x0f, 0x9a, 0xf5, 0x17, 0xa3, 0xb0, 0x85, 0x59, + 0x09, 0xfa, 0x8a, 0x03, 0x93, 0x72, 0x6e, 0xaf, 0x84, 0x55, 0x2f, 0xf1, 0xc3, 0xa0, 0x5c, 0x64, + 0x12, 0x05, 0xdb, 0x5b, 0x52, 0x92, 0xf2, 0x5c, 0x59, 0x34, 0x61, 0x32, 0x5b, 0x82, 0xbb, 0x5a, + 0x81, 0x2e, 0x02, 0xd4, 0x9b, 0xe1, 0xa6, 0xd7, 0xa4, 0x03, 0x52, 0x1e, 0x62, 0x5d, 0x50, 0x92, + 0x61, 0x49, 0x95, 0x60, 0x0d, 0x0b, 0xdd, 0x84, 0x61, 0x8f, 0x4b, 0xff, 0xf2, 0x30, 0xeb, 0xc4, + 0x33, 0x36, 0x3a, 0x61, 0x6c, 0x27, 0x73, 0xa5, 0xfd, 0xbd, 0xe9, 0x61, 0x01, 0xc4, 0x92, 0x1d, + 0x7a, 0x1c, 0x46, 0xc2, 0x36, 0x6d, 0xb7, 0xd7, 0x2c, 0x8f, 0xb0, 0x89, 0x39, 0x29, 0xda, 0x3a, + 0xb2, 0x26, 0xe0, 0x58, 0x61, 0xa0, 0xc7, 0x60, 0x38, 0xee, 0x6c, 0xd2, 0xef, 0x58, 0x1e, 0x65, + 0x1d, 0x3b, 0x21, 0x90, 0x87, 0x2b, 0x1c, 0x8c, 0x65, 0x39, 0x7a, 0x2f, 0x94, 0x22, 0x52, 0xed, + 0x44, 0x31, 0xa1, 0x1f, 0xb6, 0x0c, 0x8c, 0xf6, 0x29, 0x81, 0x5e, 0xc2, 0x69, 0x11, 0xd6, 0xf1, + 0xd0, 0x07, 0x60, 0x82, 0x7e, 0xe0, 0x4b, 0x37, 0xdb, 0x11, 0x89, 0x63, 0xfa, 0x55, 0x4b, 0x8c, + 0xd1, 0x59, 0x51, 0x73, 0x62, 0xd1, 0x28, 0xc5, 0x19, 0x6c, 0xf4, 0x2a, 0x80, 0xa7, 0x64, 0x46, + 0x79, 0x8c, 0x0d, 0xe6, 0x8a, 0xbd, 0x19, 0xb1, 0x34, 0x3f, 0x37, 0x41, 0xbf, 0x63, 0xfa, 0x1b, + 0x6b, 0xfc, 0xe8, 0xf8, 0xd4, 0x48, 0x93, 0x24, 0xa4, 0x56, 0x1e, 0x67, 0x1d, 0x56, 0xe3, 0xb3, + 0xc0, 0xc1, 0x58, 0x96, 0xbb, 0xbf, 0x59, 0x00, 0x8d, 0x0a, 0x9a, 0x83, 0x11, 0x21, 0xd7, 0xc4, + 0x92, 0x9c, 0x7b, 0x44, 0x7e, 0x07, 0xf9, 0x05, 0x6f, 0xed, 0xe5, 0xca, 0x43, 0x55, 0x0f, 0xbd, + 0x06, 0xa5, 0x76, 0x58, 0x5b, 0x25, 0x89, 0x57, 0xf3, 0x12, 0x4f, 0xec, 0xe6, 0x16, 0x76, 0x18, + 0x49, 0x71, 0xee, 0x04, 0xfd, 0x74, 0xeb, 0x29, 0x0b, 0xac, 0xf3, 0x43, 0x4f, 0x03, 0x8a, 0x49, + 0xb4, 0xe3, 0x57, 0xc9, 0x6c, 0xb5, 0x4a, 0x55, 0x22, 0xb6, 0x00, 0x06, 0x58, 0x67, 0xa6, 0x44, + 0x67, 0x50, 0xa5, 0x0b, 0x03, 0xe7, 0xd4, 0x72, 0xbf, 0x5f, 0x80, 0x09, 0xad, 0xaf, 0x6d, 0x52, + 0x45, 0xdf, 0x76, 0xe0, 0x84, 0xda, 0xce, 0xe6, 0x76, 0xaf, 0xd2, 0x59, 0xc5, 0x37, 0x2b, 0x62, + 0xf3, 0xfb, 0x52, 0x5e, 0xea, 0xa7, 0xe0, 0xc3, 0x65, 0xfd, 0x39, 0xd1, 0x87, 0x13, 0x99, 0x52, + 0x9c, 0x6d, 0xd6, 0xd4, 0x97, 0x1d, 0x38, 0x9d, 0x47, 0x22, 0x47, 0xe6, 0x36, 0x74, 0x99, 0x6b, + 0x55, 0x78, 0x51, 0xae, 0xb4, 0x33, 0xba, 0x1c, 0xff, 0x7f, 0x05, 0x98, 0xd4, 0xa7, 0x10, 0xd3, + 0x04, 0xfe, 0xa5, 0x03, 0x67, 0x64, 0x0f, 0x30, 0x89, 0x3b, 0xcd, 0xcc, 0xf0, 0xb6, 0xac, 0x0e, + 0x2f, 0xdf, 0x49, 0x67, 0xf3, 0xf8, 0xf1, 0x61, 0x7e, 0x40, 0x0c, 0xf3, 0x99, 0x5c, 0x1c, 0x9c, + 0xdf, 0xd4, 0xa9, 0x6f, 0x3a, 0x30, 0xd5, 0x9b, 0x68, 0xce, 0xc0, 0xb7, 0xcd, 0x81, 0x7f, 0xde, + 0x5e, 0x27, 0x39, 0x7b, 0x36, 0xfc, 0xac, 0xb3, 0xfa, 0x07, 0xf8, 0xc6, 0x28, 0x74, 0xed, 0x21, + 0xe8, 0x09, 0x28, 0x09, 0x71, 0xbc, 0x12, 0xd6, 0x63, 0xd6, 0xc8, 0x11, 0xbe, 0xd6, 0x66, 0x53, + 0x30, 0xd6, 0x71, 0x50, 0x0d, 0x0a, 0xf1, 0x93, 0xa2, 0xe9, 0x16, 0xc4, 0x5b, 0xe5, 0x49, 0xa5, + 0x45, 0x0e, 0xed, 0xef, 0x4d, 0x17, 0x2a, 0x4f, 0xe2, 0x42, 0xfc, 0x24, 0xd5, 0xd4, 0xeb, 0x7e, + 0x62, 0x4f, 0x53, 0x5f, 0xf2, 0x13, 0xc5, 0x87, 0x69, 0xea, 0x4b, 0x7e, 0x82, 0x29, 0x0b, 0x7a, + 0x02, 0x69, 0x24, 0x49, 0x9b, 0xed, 0xf8, 0x56, 0x4e, 0x20, 0x97, 0x37, 0x36, 0xd6, 0x15, 0x2f, + 0xa6, 0x5f, 0x50, 0x08, 0x66, 0x5c, 0xd0, 0x9b, 0x0e, 0x1d, 0x71, 0x5e, 0x18, 0x46, 0xbb, 0x42, + 0x71, 0xb8, 0x66, 0x6f, 0x0a, 0x84, 0xd1, 0xae, 0x62, 0x2e, 0x3e, 0xa4, 0x2a, 0xc0, 0x3a, 0x6b, + 0xd6, 0xf1, 0xda, 0x56, 0xcc, 0xf4, 0x04, 0x3b, 0x1d, 0x5f, 0x58, 0xac, 0x64, 0x3a, 0xbe, 0xb0, + 0x58, 0xc1, 0x8c, 0x0b, 0xfd, 0xa0, 0x91, 0x77, 0x43, 0xe8, 0x18, 0x16, 0x3e, 0x28, 0xf6, 0x6e, + 0x98, 0x1f, 0x14, 0x7b, 0x37, 0x30, 0x65, 0x41, 0x39, 0x85, 0x71, 0xcc, 0x54, 0x0a, 0x2b, 0x9c, + 0xd6, 0x2a, 0x15, 0x93, 0xd3, 0x5a, 0xa5, 0x82, 0x29, 0x0b, 0x36, 0x49, 0xab, 0x31, 0xd3, 0x47, + 0xec, 0x4c, 0xd2, 0xf9, 0x0c, 0xa7, 0xa5, 0xf9, 0x0a, 0xa6, 0x2c, 0xa8, 0xc8, 0xf0, 0x5e, 0xee, + 0x44, 0x5c, 0x99, 0x29, 0x5d, 0x5c, 0xb3, 0x30, 0x5f, 0x28, 0x39, 0xc5, 0x6d, 0x74, 0x7f, 0x6f, + 0xba, 0xc8, 0x40, 0x98, 0x33, 0x42, 0x09, 0x0c, 0xb5, 0x9b, 0x9d, 0xba, 0xcf, 0xb5, 0xa0, 0xd2, + 0xc5, 0x75, 0x0b, 0xc7, 0x55, 0x46, 0x4f, 0xf1, 0x84, 0xfd, 0xbd, 0xe9, 0x21, 0x0e, 0xc3, 0x82, + 0x97, 0xfb, 0xfb, 0x03, 0xa9, 0x90, 0x92, 0xbb, 0x08, 0xfa, 0x35, 0xb6, 0xfd, 0x0a, 0x09, 0x24, + 0x14, 0x6e, 0xe7, 0xd8, 0x14, 0xee, 0x53, 0x7c, 0x9f, 0x35, 0xd8, 0xe1, 0x2c, 0x7f, 0xf4, 0x45, + 0xa7, 0xfb, 0x44, 0xed, 0xd9, 0xdf, 0x41, 0x53, 0x75, 0x80, 0xef, 0x50, 0x07, 0x1e, 0xb4, 0xa7, + 0xde, 0x74, 0x52, 0xd5, 0x25, 0xee, 0xb5, 0xfb, 0x7c, 0xcc, 0xdc, 0x7d, 0x2c, 0x9a, 0x01, 0xf4, + 0xdd, 0xe6, 0x73, 0x0e, 0x8c, 0x4b, 0x38, 0x55, 0xca, 0x63, 0x74, 0x13, 0x46, 0x64, 0x4b, 0xc5, + 0xd7, 0xb3, 0x69, 0x81, 0x50, 0x47, 0x07, 0xd5, 0x18, 0xc5, 0xcd, 0xfd, 0xf6, 0x30, 0xa0, 0x74, + 0x87, 0x6c, 0x87, 0xb1, 0xcf, 0xe4, 0xdf, 0x11, 0xf6, 0xbe, 0x40, 0xdb, 0xfb, 0x9e, 0xb5, 0xb9, + 0xf7, 0xa5, 0xcd, 0x32, 0x76, 0xc1, 0x2f, 0x66, 0x76, 0x0b, 0xbe, 0x1d, 0x7e, 0xf4, 0x58, 0x76, + 0x0b, 0xad, 0x09, 0x07, 0xef, 0x1b, 0x3b, 0x62, 0xdf, 0xe0, 0x1b, 0xe6, 0x2f, 0xda, 0xdd, 0x37, + 0xb4, 0x56, 0x64, 0x77, 0x90, 0x88, 0xcb, 0x75, 0xbe, 0x63, 0x5e, 0xb7, 0x2a, 0xd7, 0x35, 0xae, + 0xa6, 0x84, 0x8f, 0xb8, 0x84, 0x1f, 0xb2, 0xc5, 0x53, 0x93, 0xf0, 0x59, 0x9e, 0x4a, 0xd6, 0xbf, + 0x2c, 0x65, 0x3d, 0xdf, 0x2b, 0x9f, 0xb3, 0x2c, 0xeb, 0x35, 0xbe, 0xdd, 0x52, 0xff, 0x75, 0x25, + 0xf5, 0x47, 0x6c, 0xe9, 0xa6, 0xa6, 0xd4, 0xd7, 0xb8, 0xe7, 0xc9, 0xff, 0x97, 0xe0, 0x4c, 0x37, + 0x26, 0x26, 0x5b, 0xe8, 0x02, 0x8c, 0x56, 0xc3, 0x60, 0xcb, 0xaf, 0xaf, 0x7a, 0x6d, 0x71, 0x4a, + 0x55, 0xb2, 0x70, 0x5e, 0x16, 0xe0, 0x14, 0x07, 0x3d, 0xc0, 0x05, 0x1f, 0xb7, 0x03, 0x95, 0x04, + 0xea, 0xc0, 0x32, 0xd9, 0x65, 0x52, 0xf0, 0x7d, 0x23, 0x5f, 0xf9, 0xfa, 0xf4, 0x3d, 0x9f, 0xf8, + 0x0f, 0x0f, 0xde, 0xe3, 0xfe, 0xe1, 0x00, 0xdc, 0x97, 0xcb, 0x53, 0x9c, 0x51, 0xfe, 0xb1, 0x71, + 0x46, 0xd1, 0xca, 0x85, 0x14, 0xbb, 0x6e, 0x53, 0x7d, 0xd7, 0xc8, 0xe7, 0x9d, 0x46, 0xb4, 0x62, + 0x9c, 0xdf, 0x28, 0x3a, 0x50, 0x81, 0xd7, 0x22, 0x71, 0xdb, 0xab, 0x12, 0xd1, 0x7b, 0x35, 0x50, + 0x57, 0x65, 0x01, 0x4e, 0x71, 0xb8, 0xe1, 0x60, 0xcb, 0xeb, 0x34, 0x13, 0x61, 0x1e, 0xd4, 0x0c, + 0x07, 0x0c, 0x8c, 0x65, 0x39, 0xfa, 0x3b, 0x0e, 0xa0, 0x6e, 0xae, 0x42, 0x10, 0x6c, 0x1c, 0xc7, + 0x38, 0xcc, 0x9d, 0xdd, 0xd7, 0x4c, 0x0f, 0x5a, 0x4f, 0x73, 0xda, 0xa1, 0x7d, 0xd3, 0xd7, 0xd3, + 0x7d, 0x90, 0x1f, 0x89, 0xfa, 0xb0, 0x1c, 0x32, 0x03, 0x53, 0xb5, 0x4a, 0xe2, 0x98, 0x1b, 0x21, + 0x75, 0x03, 0x13, 0x03, 0x63, 0x59, 0x8e, 0xa6, 0xa1, 0x48, 0xa2, 0x28, 0x8c, 0x84, 0x85, 0x81, + 0x2d, 0xa3, 0x4b, 0x14, 0x80, 0x39, 0xdc, 0xfd, 0x51, 0x01, 0xca, 0xbd, 0xce, 0x64, 0xe8, 0x77, + 0x34, 0x6b, 0x82, 0x38, 0x2f, 0x8a, 0xe3, 0x6e, 0x78, 0x7c, 0x27, 0xc1, 0xec, 0xb1, 0xb7, 0x87, + 0x5d, 0x41, 0x94, 0xe2, 0x6c, 0x03, 0xa7, 0xde, 0xd2, 0xec, 0x0a, 0x3a, 0x89, 0x1c, 0x05, 0x63, + 0xcb, 0x54, 0x30, 0xd6, 0x6d, 0x77, 0x4a, 0x57, 0x33, 0xfe, 0xb8, 0x08, 0xa7, 0x64, 0x69, 0x85, + 0xd0, 0xad, 0xfa, 0x99, 0x0e, 0x89, 0x76, 0xd1, 0x1f, 0x39, 0x70, 0xda, 0xcb, 0x1a, 0xac, 0x7c, + 0x72, 0x0c, 0x03, 0xad, 0x71, 0x9d, 0x99, 0xcd, 0xe1, 0xc8, 0x07, 0xfa, 0xa2, 0x18, 0xe8, 0xd3, + 0x79, 0x28, 0x3d, 0xbc, 0x0d, 0xb9, 0x1d, 0x40, 0x4f, 0xc1, 0x98, 0x84, 0x33, 0x23, 0x17, 0x5f, + 0xe2, 0xca, 0xa4, 0x3f, 0xab, 0x95, 0x61, 0x03, 0x93, 0xd6, 0x4c, 0x48, 0xab, 0xdd, 0xf4, 0x12, + 0xa2, 0x99, 0xc7, 0x54, 0xcd, 0x0d, 0xad, 0x0c, 0x1b, 0x98, 0xe8, 0x11, 0x18, 0x0a, 0xc2, 0x1a, + 0xb9, 0x52, 0x13, 0x66, 0xf1, 0x09, 0x51, 0x67, 0xe8, 0x2a, 0x83, 0x62, 0x51, 0x8a, 0x1e, 0x4e, + 0x6d, 0x90, 0x45, 0xb6, 0x84, 0x4a, 0x79, 0xf6, 0x47, 0xf4, 0xf7, 0x1d, 0x18, 0xa5, 0x35, 0x36, + 0x76, 0xdb, 0x84, 0xee, 0xad, 0xf4, 0x8b, 0xd4, 0x8e, 0xe7, 0x8b, 0x5c, 0x95, 0x6c, 0x4c, 0x03, + 0xcf, 0xa8, 0x82, 0xbf, 0xf1, 0xf6, 0xf4, 0x88, 0xfc, 0x81, 0xd3, 0x56, 0x4d, 0x2d, 0xc1, 0xbd, + 0x3d, 0xbf, 0xe6, 0xa1, 0x1c, 0x20, 0x7f, 0x1d, 0x26, 0xcc, 0x46, 0x1c, 0xca, 0xfb, 0xf1, 0xcf, + 0xb4, 0x65, 0xc7, 0xfb, 0x25, 0xe4, 0xd9, 0x3b, 0xa6, 0x4d, 0xab, 0xc9, 0xb0, 0x20, 0xa6, 0x9e, + 0x39, 0x19, 0x16, 0xc4, 0x64, 0x58, 0x70, 0xff, 0xc0, 0x49, 0x97, 0xa6, 0xa6, 0x66, 0xd2, 0x8d, + 0xb9, 0x13, 0x35, 0x85, 0x20, 0x56, 0x1b, 0xf3, 0x35, 0xbc, 0x82, 0x29, 0x1c, 0xbd, 0xa5, 0x49, + 0x47, 0x5a, 0xad, 0x23, 0x9c, 0x39, 0x96, 0x1c, 0x13, 0x06, 0xe1, 0x6e, 0xf9, 0x27, 0x0a, 0x70, + 0xb6, 0x09, 0xee, 0x17, 0x0b, 0xf0, 0xc0, 0x81, 0x4a, 0x73, 0x6e, 0xc3, 0x9d, 0x77, 0xbc, 0xe1, + 0x74, 0x5b, 0x8b, 0x48, 0x3b, 0xbc, 0x86, 0x57, 0xc4, 0xf7, 0x52, 0xdb, 0x1a, 0xe6, 0x60, 0x2c, + 0xcb, 0xa9, 0xea, 0xb0, 0x4d, 0x76, 0x17, 0xc3, 0xa8, 0xe5, 0x25, 0x42, 0x3a, 0x28, 0xd5, 0x61, + 0x59, 0x16, 0xe0, 0x14, 0xc7, 0xfd, 0x23, 0x07, 0xb2, 0x0d, 0x40, 0x1e, 0x4c, 0x74, 0x62, 0x12, + 0xd1, 0x2d, 0xb5, 0x42, 0xaa, 0x11, 0x91, 0xd3, 0xf3, 0xe1, 0x19, 0x1e, 0xe3, 0x40, 0x7b, 0x38, + 0x53, 0x0d, 0x23, 0x32, 0xb3, 0xf3, 0xc4, 0x0c, 0xc7, 0x58, 0x26, 0xbb, 0x15, 0xd2, 0x24, 0x94, + 0xc6, 0x1c, 0xda, 0xdf, 0x9b, 0x9e, 0xb8, 0x66, 0x10, 0xc0, 0x19, 0x82, 0x94, 0x45, 0xdb, 0x8b, + 0xe3, 0x1b, 0x61, 0x54, 0x13, 0x2c, 0x0a, 0x87, 0x66, 0xb1, 0x6e, 0x10, 0xc0, 0x19, 0x82, 0xee, + 0xf7, 0xe9, 0xf1, 0x55, 0xd7, 0x9a, 0xd1, 0xd7, 0xa9, 0xee, 0x43, 0x21, 0x73, 0xcd, 0x70, 0x73, + 0x3e, 0x0c, 0x12, 0xcf, 0x0f, 0x88, 0x0c, 0x91, 0xd8, 0xb0, 0xa4, 0xa3, 0x1b, 0xb4, 0x53, 0xcf, + 0x45, 0x77, 0x19, 0xce, 0x69, 0x0b, 0xd5, 0x71, 0x36, 0x9b, 0xe1, 0x66, 0xd6, 0xf7, 0x49, 0x91, + 0x30, 0x2b, 0x71, 0x7f, 0xe2, 0xc0, 0xb9, 0x1e, 0x87, 0x01, 0xf4, 0x65, 0x07, 0xc6, 0x37, 0x7f, + 0x2a, 0xfa, 0x66, 0x36, 0x03, 0x7d, 0x00, 0x26, 0x28, 0x80, 0xee, 0x44, 0x62, 0x6e, 0x16, 0x4c, + 0xbf, 0xdc, 0x9c, 0x51, 0x8a, 0x33, 0xd8, 0xee, 0xaf, 0x17, 0x20, 0x87, 0x0b, 0x7a, 0x1c, 0x46, + 0x48, 0x50, 0x6b, 0x87, 0x7e, 0x90, 0x08, 0x61, 0xa4, 0xa4, 0xde, 0x25, 0x01, 0xc7, 0x0a, 0x43, + 0x9c, 0x3f, 0xc4, 0xc0, 0x14, 0xba, 0xce, 0x1f, 0xa2, 0xe5, 0x29, 0x0e, 0xaa, 0xc3, 0xa4, 0xc7, + 0xbd, 0x4a, 0x6c, 0xee, 0xb1, 0x69, 0x3a, 0x70, 0x98, 0x69, 0x7a, 0x9a, 0x39, 0x7d, 0x33, 0x24, + 0x70, 0x17, 0x51, 0xf4, 0x5e, 0x28, 0x75, 0x62, 0x52, 0x59, 0x58, 0x9e, 0x8f, 0x48, 0x8d, 0x9f, + 0xca, 0x35, 0x6f, 0xe7, 0xb5, 0xb4, 0x08, 0xeb, 0x78, 0xee, 0x9f, 0x38, 0x30, 0x3c, 0xe7, 0x55, + 0xb7, 0xc3, 0xad, 0x2d, 0x3a, 0x14, 0xb5, 0x4e, 0x94, 0x1a, 0xd6, 0xb4, 0xa1, 0x58, 0x10, 0x70, + 0xac, 0x30, 0xd0, 0x06, 0x0c, 0xf1, 0x05, 0x2f, 0x96, 0xdd, 0xcf, 0x6b, 0xfd, 0x51, 0xd1, 0x4b, + 0x6c, 0x3a, 0x74, 0x12, 0xbf, 0x39, 0xc3, 0xa3, 0x97, 0x66, 0xae, 0x04, 0xc9, 0x5a, 0x54, 0x49, + 0x22, 0x3f, 0xa8, 0xf3, 0x93, 0xdf, 0x22, 0xa3, 0x81, 0x05, 0x2d, 0xda, 0x8d, 0x96, 0x77, 0x53, + 0xb2, 0x13, 0xe2, 0x47, 0x75, 0x63, 0x35, 0x2d, 0xc2, 0x3a, 0x1e, 0xdd, 0x4d, 0xaa, 0x5e, 0x5b, + 0xe8, 0x25, 0x6a, 0x37, 0x99, 0xf7, 0xda, 0x98, 0xc2, 0xdd, 0x3f, 0x74, 0x60, 0x74, 0xce, 0x8b, + 0xfd, 0xea, 0x5f, 0x20, 0xd9, 0xf4, 0x11, 0x28, 0xce, 0x7b, 0xd5, 0x06, 0x41, 0xd7, 0xb2, 0x67, + 0xe2, 0xd2, 0xc5, 0x47, 0xf3, 0xd8, 0xa8, 0xf3, 0xb1, 0xce, 0x69, 0xbc, 0xd7, 0xc9, 0xd9, 0x7d, + 0xdb, 0x81, 0x89, 0xf9, 0xa6, 0x4f, 0x82, 0x64, 0x9e, 0x44, 0x09, 0x1b, 0xb8, 0x3a, 0x4c, 0x56, + 0x15, 0xe4, 0x28, 0x43, 0xc7, 0x26, 0xf3, 0x7c, 0x86, 0x04, 0xee, 0x22, 0x8a, 0x6a, 0x70, 0x82, + 0xc3, 0xd2, 0x45, 0x73, 0xa8, 0xf1, 0x63, 0xc6, 0xdb, 0x79, 0x93, 0x02, 0xce, 0x92, 0x74, 0x7f, + 0xec, 0xc0, 0xb9, 0xf9, 0x66, 0x27, 0x4e, 0x48, 0x74, 0x5d, 0x08, 0x2b, 0xa9, 0xfd, 0xa2, 0x8f, + 0xc1, 0x48, 0x4b, 0xba, 0xb1, 0x9d, 0xdb, 0xcc, 0x6f, 0x26, 0xee, 0x28, 0x36, 0x6d, 0xcc, 0xda, + 0xe6, 0x8b, 0xa4, 0x9a, 0xac, 0x92, 0xc4, 0x4b, 0x63, 0x2e, 0x52, 0x18, 0x56, 0x54, 0x51, 0x1b, + 0x06, 0xe3, 0x36, 0xa9, 0xda, 0x0b, 0x79, 0x93, 0x7d, 0xa8, 0xb4, 0x49, 0x35, 0x15, 0xfb, 0xcc, + 0x01, 0xcb, 0x38, 0xb9, 0xff, 0xdb, 0x81, 0xfb, 0x7a, 0xf4, 0x77, 0xc5, 0x8f, 0x13, 0xf4, 0x42, + 0x57, 0x9f, 0x67, 0xfa, 0xeb, 0x33, 0xad, 0xcd, 0x7a, 0xac, 0xe4, 0x85, 0x84, 0x68, 0xfd, 0x7d, + 0x1d, 0x8a, 0x7e, 0x42, 0x5a, 0xd2, 0x4a, 0x6e, 0xc1, 0x9e, 0xd5, 0xa3, 0x2f, 0x73, 0xe3, 0x32, + 0xf0, 0xf1, 0x0a, 0xe5, 0x87, 0x39, 0x5b, 0x77, 0x1b, 0x86, 0xe6, 0xc3, 0x66, 0xa7, 0x15, 0xf4, + 0x17, 0x3e, 0x94, 0xec, 0xb6, 0x49, 0x76, 0x0b, 0x65, 0xa7, 0x03, 0x56, 0x22, 0xed, 0x4a, 0x03, + 0xf9, 0x76, 0x25, 0xf7, 0x5f, 0x39, 0x40, 0x57, 0x55, 0xcd, 0x17, 0xee, 0x55, 0x4e, 0x8e, 0x33, + 0x7c, 0x40, 0x27, 0x77, 0x6b, 0x6f, 0x7a, 0x5c, 0x21, 0x6a, 0xf4, 0x3f, 0x02, 0x43, 0x31, 0x3b, + 0xb1, 0x8b, 0x36, 0x2c, 0x4a, 0xf5, 0x9a, 0x9f, 0xe3, 0x6f, 0xed, 0x4d, 0xf7, 0x15, 0xcb, 0x3a, + 0xa3, 0x68, 0x0b, 0x4f, 0xb0, 0xa0, 0x4a, 0xf5, 0xc1, 0x16, 0x89, 0x63, 0xaf, 0x2e, 0x0f, 0x80, + 0x4a, 0x1f, 0x5c, 0xe5, 0x60, 0x2c, 0xcb, 0xdd, 0x2f, 0x39, 0x30, 0xae, 0xf6, 0x36, 0xaa, 0xdd, + 0xa3, 0xab, 0xfa, 0x2e, 0xc8, 0x67, 0xca, 0x03, 0x3d, 0x24, 0x8e, 0xd8, 0xe7, 0x0f, 0xde, 0x24, + 0xdf, 0x03, 0x63, 0x35, 0xd2, 0x26, 0x41, 0x8d, 0x04, 0x55, 0x7a, 0x3a, 0xa7, 0x33, 0x64, 0x74, + 0x6e, 0x92, 0x1e, 0x47, 0x17, 0x34, 0x38, 0x36, 0xb0, 0xdc, 0x6f, 0x38, 0x70, 0xaf, 0x22, 0x57, + 0x21, 0x09, 0x26, 0x49, 0xb4, 0xab, 0x62, 0x57, 0x0f, 0xb7, 0x99, 0x5d, 0xa7, 0xea, 0x71, 0x12, + 0x71, 0xe6, 0x47, 0xdb, 0xcd, 0x4a, 0x5c, 0x99, 0x66, 0x44, 0xb0, 0xa4, 0xe6, 0xfe, 0xea, 0x00, + 0x9c, 0xd6, 0x1b, 0xa9, 0x04, 0xcc, 0x27, 0x1d, 0x00, 0x35, 0x02, 0x74, 0xbf, 0x1e, 0xb0, 0xe3, + 0xd0, 0x33, 0xbe, 0x54, 0x2a, 0x82, 0x14, 0x38, 0xc6, 0x1a, 0x5b, 0xf4, 0x1c, 0x8c, 0xed, 0xd0, + 0x45, 0x41, 0x56, 0xa9, 0x36, 0x11, 0x97, 0x07, 0x58, 0x33, 0xa6, 0xf3, 0x3e, 0xe6, 0xb3, 0x29, + 0x5e, 0x6a, 0x2d, 0xd0, 0x80, 0x31, 0x36, 0x48, 0xd1, 0x83, 0xd0, 0x78, 0xa4, 0x7f, 0x12, 0x61, + 0xb2, 0xff, 0xb0, 0xc5, 0x3e, 0x66, 0xbf, 0xfa, 0xdc, 0xc9, 0xfd, 0xbd, 0xe9, 0x71, 0x03, 0x84, + 0xcd, 0x46, 0xb8, 0xcf, 0x01, 0x1b, 0x0b, 0x3f, 0xe8, 0x90, 0xb5, 0x00, 0x3d, 0x24, 0x4d, 0x78, + 0xdc, 0xed, 0xa3, 0x24, 0x87, 0x6e, 0xc6, 0xa3, 0x47, 0xdd, 0x2d, 0xcf, 0x6f, 0xb2, 0x98, 0x4e, + 0x8a, 0xa5, 0x8e, 0xba, 0x8b, 0x0c, 0x8a, 0x45, 0xa9, 0x3b, 0x03, 0xc3, 0xf3, 0xb4, 0xef, 0x24, + 0xa2, 0x74, 0xf5, 0x50, 0xec, 0x71, 0x23, 0x14, 0x5b, 0x86, 0x5c, 0x6f, 0xc0, 0x99, 0xf9, 0x88, + 0x78, 0x09, 0xa9, 0x3c, 0x39, 0xd7, 0xa9, 0x6e, 0x93, 0x84, 0xc7, 0xbb, 0xc5, 0xe8, 0xfd, 0x30, + 0x1e, 0xb2, 0x2d, 0x63, 0x25, 0xac, 0x6e, 0xfb, 0x41, 0x5d, 0x58, 0x64, 0xcf, 0x08, 0x2a, 0xe3, + 0x6b, 0x7a, 0x21, 0x36, 0x71, 0xdd, 0xff, 0x54, 0x80, 0xb1, 0xf9, 0x28, 0x0c, 0xa4, 0x58, 0xbc, + 0x0b, 0x5b, 0x59, 0x62, 0x6c, 0x65, 0x16, 0xbc, 0xb1, 0x7a, 0xfb, 0x7b, 0x6d, 0x67, 0xe8, 0x55, + 0x25, 0x22, 0x07, 0x6c, 0x9d, 0x50, 0x0c, 0xbe, 0x8c, 0x76, 0xfa, 0xb1, 0x4d, 0x01, 0xea, 0xfe, + 0x67, 0x07, 0x26, 0x75, 0xf4, 0xbb, 0xb0, 0x83, 0xc6, 0xe6, 0x0e, 0x7a, 0xd5, 0x6e, 0x7f, 0x7b, + 0x6c, 0x9b, 0x6f, 0x0f, 0x9b, 0xfd, 0x64, 0xae, 0xf8, 0xaf, 0x38, 0x30, 0x76, 0x43, 0x03, 0x88, + 0xce, 0xda, 0x56, 0x62, 0xde, 0x25, 0xc5, 0x8c, 0x0e, 0xbd, 0x95, 0xf9, 0x8d, 0x8d, 0x96, 0x50, + 0xb9, 0x1f, 0x57, 0x1b, 0xa4, 0xd6, 0x69, 0xca, 0xed, 0x5b, 0x0d, 0x69, 0x45, 0xc0, 0xb1, 0xc2, + 0x40, 0x2f, 0xc0, 0xc9, 0x6a, 0x18, 0x54, 0x3b, 0x51, 0x44, 0x82, 0xea, 0xee, 0x3a, 0xbb, 0x38, + 0x22, 0x36, 0xc4, 0x19, 0x51, 0xed, 0xe4, 0x7c, 0x16, 0xe1, 0x56, 0x1e, 0x10, 0x77, 0x13, 0xe2, + 0xbe, 0x84, 0x98, 0x6e, 0x59, 0xe2, 0x3c, 0xa6, 0xf9, 0x12, 0x18, 0x18, 0xcb, 0x72, 0x74, 0x0d, + 0xce, 0xc5, 0x89, 0x17, 0x25, 0x7e, 0x50, 0x5f, 0x20, 0x5e, 0xad, 0xe9, 0x07, 0xf4, 0x28, 0x11, + 0x06, 0x35, 0xee, 0xe9, 0x1c, 0x98, 0xbb, 0x6f, 0x7f, 0x6f, 0xfa, 0x5c, 0x25, 0x1f, 0x05, 0xf7, + 0xaa, 0x8b, 0x3e, 0x02, 0x53, 0xc2, 0x5b, 0xb1, 0xd5, 0x69, 0x3e, 0x1d, 0x6e, 0xc6, 0x97, 0xfd, + 0x98, 0x1e, 0xf3, 0x57, 0xfc, 0x96, 0x9f, 0x30, 0x7f, 0x66, 0x71, 0xee, 0xfc, 0xfe, 0xde, 0xf4, + 0x54, 0xa5, 0x27, 0x16, 0x3e, 0x80, 0x02, 0xc2, 0x70, 0x96, 0x0b, 0xbf, 0x2e, 0xda, 0xc3, 0x8c, + 0xf6, 0xd4, 0xfe, 0xde, 0xf4, 0xd9, 0xc5, 0x5c, 0x0c, 0xdc, 0xa3, 0x26, 0xfd, 0x82, 0x89, 0xdf, + 0x22, 0x2f, 0x87, 0x01, 0x61, 0xee, 0x47, 0xed, 0x0b, 0x6e, 0x08, 0x38, 0x56, 0x18, 0xe8, 0xc5, + 0x74, 0x26, 0xd2, 0xe5, 0x22, 0xa2, 0x70, 0x0e, 0x2f, 0xe1, 0xd8, 0xd1, 0xe4, 0xba, 0x46, 0x89, + 0x85, 0x97, 0x1a, 0xb4, 0xd1, 0xa7, 0x1c, 0x18, 0x8b, 0x93, 0x50, 0x5d, 0xf6, 0x10, 0x61, 0x38, + 0x16, 0xa6, 0x7d, 0x45, 0xa3, 0xca, 0x15, 0x1f, 0x1d, 0x82, 0x0d, 0xae, 0xe8, 0xe7, 0x60, 0x54, + 0x4e, 0xe0, 0xb8, 0x5c, 0x62, 0xba, 0x12, 0x3b, 0xc6, 0xc9, 0xf9, 0x1d, 0xe3, 0xb4, 0x9c, 0xaa, + 0xb2, 0x37, 0x1a, 0x24, 0x60, 0x81, 0xc8, 0x9a, 0x2a, 0x7b, 0xbd, 0x41, 0x02, 0xcc, 0x4a, 0xdc, + 0x1f, 0x0d, 0x00, 0xea, 0x16, 0x7c, 0x68, 0x19, 0x86, 0xbc, 0x6a, 0xe2, 0xef, 0xc8, 0x20, 0xcc, + 0x87, 0xf2, 0x94, 0x02, 0x3e, 0x80, 0x98, 0x6c, 0x11, 0x3a, 0xef, 0x49, 0x2a, 0x2d, 0x67, 0x59, + 0x55, 0x2c, 0x48, 0xa0, 0x10, 0x4e, 0x36, 0xbd, 0x38, 0x91, 0x2d, 0xac, 0xd1, 0x0f, 0x29, 0xb6, + 0x8b, 0x9f, 0xed, 0xef, 0x53, 0xd1, 0x1a, 0x73, 0x67, 0xe8, 0x7a, 0x5c, 0xc9, 0x12, 0xc2, 0xdd, + 0xb4, 0xd1, 0xc7, 0x99, 0x76, 0xc5, 0x55, 0x5f, 0xa9, 0xd6, 0x2c, 0x5b, 0xd1, 0x3c, 0x38, 0x4d, + 0x43, 0xb3, 0x12, 0x6c, 0xb0, 0xc6, 0x12, 0x5d, 0x80, 0x51, 0xb6, 0x6e, 0x48, 0x8d, 0xf0, 0xd5, + 0x3f, 0x90, 0x2a, 0xc1, 0x15, 0x59, 0x80, 0x53, 0x1c, 0x4d, 0xcb, 0xe0, 0x0b, 0xbe, 0x87, 0x96, + 0x81, 0x9e, 0x82, 0x62, 0xbb, 0xe1, 0xc5, 0x32, 0xb0, 0xdf, 0x95, 0x52, 0x7b, 0x9d, 0x02, 0x99, + 0x68, 0xd2, 0xbe, 0x25, 0x03, 0x62, 0x5e, 0xc1, 0xfd, 0xd7, 0x00, 0xc3, 0x0b, 0xb3, 0x4b, 0x1b, + 0x5e, 0xbc, 0xdd, 0xc7, 0x19, 0x88, 0x2e, 0x43, 0xa1, 0xac, 0x66, 0x05, 0xa9, 0x54, 0x62, 0xb1, + 0xc2, 0x40, 0x01, 0x0c, 0xf9, 0x01, 0x95, 0x3c, 0xe5, 0x09, 0x5b, 0x6e, 0x08, 0x75, 0x9e, 0x63, + 0x76, 0xa2, 0x2b, 0x8c, 0x3a, 0x16, 0x5c, 0xd0, 0xab, 0x30, 0xea, 0xc9, 0x7b, 0x55, 0x62, 0xff, + 0x5f, 0xb6, 0x61, 0x5f, 0x17, 0x24, 0xf5, 0x08, 0x2b, 0x01, 0xc2, 0x29, 0x43, 0xf4, 0x09, 0x07, + 0x4a, 0xb2, 0xeb, 0x98, 0x6c, 0x09, 0xd7, 0xf7, 0xaa, 0xbd, 0x3e, 0x63, 0xb2, 0xc5, 0xc3, 0x6f, + 0x34, 0x00, 0xd6, 0x59, 0x76, 0x9d, 0x99, 0x8a, 0xfd, 0x9c, 0x99, 0xd0, 0x0d, 0x18, 0xbd, 0xe1, + 0x27, 0x0d, 0xb6, 0xc3, 0x0b, 0x97, 0xdb, 0xe2, 0x9d, 0xb7, 0x9a, 0x92, 0x4b, 0x47, 0xec, 0xba, + 0x64, 0x80, 0x53, 0x5e, 0x74, 0x39, 0xd0, 0x1f, 0xec, 0x5e, 0x1a, 0xdb, 0x1b, 0x46, 0xcd, 0x0a, + 0xac, 0x00, 0xa7, 0x38, 0x74, 0x88, 0xc7, 0xe8, 0xaf, 0x0a, 0x79, 0xa9, 0x43, 0x45, 0x8b, 0x88, + 0x44, 0xb1, 0x30, 0xaf, 0x24, 0x45, 0x3e, 0x58, 0xd7, 0x35, 0x1e, 0xd8, 0xe0, 0xa8, 0x44, 0xe7, + 0x68, 0x2f, 0xd1, 0x89, 0x5e, 0xe5, 0x67, 0x38, 0x7e, 0x98, 0x10, 0xbb, 0xc1, 0x8a, 0x9d, 0xf3, + 0x0d, 0xa7, 0xc9, 0xef, 0x7a, 0xa4, 0xbf, 0xb1, 0xc6, 0x8f, 0x4a, 0x8c, 0x30, 0xb8, 0x74, 0xd3, + 0x4f, 0xc4, 0x0d, 0x15, 0x25, 0x31, 0xd6, 0x18, 0x14, 0x8b, 0x52, 0x1e, 0xda, 0x41, 0x27, 0x41, + 0x2c, 0x76, 0x01, 0x2d, 0xb4, 0x83, 0x81, 0xb1, 0x2c, 0x47, 0x7f, 0xd7, 0x81, 0x62, 0x23, 0x0c, + 0xb7, 0xe3, 0xf2, 0x38, 0x9b, 0x1c, 0x16, 0x74, 0x6a, 0x21, 0x71, 0x66, 0x2e, 0x53, 0xb2, 0xe6, + 0x9d, 0xbb, 0x22, 0x83, 0xdd, 0xda, 0x9b, 0x9e, 0x58, 0xf1, 0xb7, 0x48, 0x75, 0xb7, 0xda, 0x24, + 0x0c, 0xf2, 0xc6, 0xdb, 0x1a, 0xe4, 0xd2, 0x0e, 0x09, 0x12, 0xcc, 0x5b, 0x35, 0xf5, 0x39, 0x07, + 0x20, 0x25, 0x94, 0xe3, 0x43, 0x25, 0x66, 0xd4, 0x81, 0x85, 0x03, 0xb5, 0xd1, 0x34, 0xdd, 0x29, + 0xfb, 0x6f, 0x1d, 0x28, 0xd1, 0xce, 0x49, 0x11, 0xf8, 0x08, 0x0c, 0x25, 0x5e, 0x54, 0x27, 0xd2, + 0x8f, 0xa0, 0x3e, 0xc7, 0x06, 0x83, 0x62, 0x51, 0x8a, 0x02, 0x28, 0x26, 0x5e, 0xbc, 0x2d, 0xd5, + 0xf8, 0x2b, 0xd6, 0x86, 0x38, 0xd5, 0xe0, 0xe9, 0xaf, 0x18, 0x73, 0x36, 0xe8, 0x51, 0x18, 0xa1, + 0x5b, 0xc7, 0xa2, 0x17, 0xcb, 0xd0, 0x9e, 0x31, 0x2a, 0xc4, 0x17, 0x05, 0x0c, 0xab, 0x52, 0xf7, + 0xd7, 0x0b, 0x30, 0xb8, 0xc0, 0x0f, 0x74, 0x43, 0x71, 0xd8, 0x89, 0xaa, 0x44, 0x28, 0xf6, 0x16, + 0xe6, 0x34, 0xa5, 0x5b, 0x61, 0x34, 0xb5, 0x23, 0x15, 0xfb, 0x8d, 0x05, 0x2f, 0xf4, 0x96, 0x03, + 0x13, 0x49, 0xe4, 0x05, 0xf1, 0x16, 0xf3, 0xd8, 0xf8, 0x61, 0x20, 0x86, 0xc8, 0xc2, 0x2c, 0xdc, + 0x30, 0xe8, 0x56, 0x12, 0xd2, 0x4e, 0x1d, 0x47, 0x66, 0x19, 0xce, 0xb4, 0xc1, 0xfd, 0x0d, 0x07, + 0x20, 0x6d, 0x3d, 0x7a, 0xd3, 0x81, 0x71, 0x4f, 0x0f, 0x69, 0x15, 0x63, 0xb4, 0x66, 0xcf, 0xbd, + 0xcb, 0xc8, 0x72, 0x5b, 0x86, 0x01, 0xc2, 0x26, 0x63, 0xf7, 0xbd, 0x50, 0x64, 0xab, 0x83, 0x1d, + 0x7a, 0x84, 0xed, 0x3b, 0x6b, 0xec, 0x92, 0x36, 0x71, 0xac, 0x30, 0xdc, 0x17, 0x60, 0xe2, 0xd2, + 0x4d, 0x52, 0xed, 0x24, 0x61, 0xc4, 0x2d, 0xff, 0x3d, 0x2e, 0x4e, 0x39, 0x47, 0xba, 0x38, 0xf5, + 0x1d, 0x07, 0x4a, 0x5a, 0x7c, 0x23, 0xdd, 0xa9, 0xeb, 0xf3, 0x15, 0x6e, 0xe0, 0x10, 0x43, 0xb5, + 0x6c, 0x25, 0x82, 0x92, 0x93, 0x4c, 0xb7, 0x11, 0x05, 0xc2, 0x29, 0xc3, 0xdb, 0xc4, 0xff, 0xb9, + 0xbf, 0xef, 0xc0, 0x99, 0xdc, 0x60, 0xcc, 0x77, 0xb8, 0xd9, 0x86, 0x0f, 0xbe, 0xd0, 0x87, 0x0f, + 0xfe, 0xb7, 0x1d, 0x48, 0x29, 0x51, 0x51, 0xb4, 0x99, 0xb6, 0x5c, 0x13, 0x45, 0x82, 0x93, 0x28, + 0x45, 0xaf, 0xc2, 0x39, 0xf3, 0x0b, 0x1e, 0xd1, 0xdf, 0xc2, 0x0f, 0xa7, 0xf9, 0x94, 0x70, 0x2f, + 0x16, 0xee, 0x57, 0x1d, 0x28, 0x2e, 0x79, 0x9d, 0x3a, 0xe9, 0xcb, 0x5c, 0x46, 0xe5, 0x58, 0x44, + 0xbc, 0x66, 0x22, 0x8f, 0x0e, 0x42, 0x8e, 0x61, 0x01, 0xc3, 0xaa, 0x14, 0xcd, 0xc2, 0x68, 0xd8, + 0x26, 0x86, 0x0b, 0xf1, 0x21, 0x39, 0x7a, 0x6b, 0xb2, 0x80, 0x6e, 0x3b, 0x8c, 0xbb, 0x82, 0xe0, + 0xb4, 0x96, 0xfb, 0xb5, 0x21, 0x28, 0x69, 0x97, 0x85, 0xa8, 0x2e, 0x10, 0x91, 0x76, 0x98, 0xd5, + 0x97, 0xe9, 0x84, 0xc1, 0xac, 0x84, 0xae, 0xc1, 0x88, 0xec, 0xf8, 0x31, 0x17, 0x5b, 0xc6, 0x1a, + 0xc4, 0x02, 0x8e, 0x15, 0x06, 0x9a, 0x86, 0x62, 0x8d, 0xb4, 0x93, 0x06, 0x6b, 0xde, 0x20, 0x8f, + 0x1d, 0x5c, 0xa0, 0x00, 0xcc, 0xe1, 0x14, 0x61, 0x8b, 0x24, 0xd5, 0x06, 0xb3, 0x0c, 0x8b, 0xe0, + 0xc2, 0x45, 0x0a, 0xc0, 0x1c, 0x9e, 0xe3, 0xc5, 0x2c, 0x1e, 0xbf, 0x17, 0x73, 0xc8, 0xb2, 0x17, + 0x13, 0xb5, 0xe1, 0x54, 0x1c, 0x37, 0xd6, 0x23, 0x7f, 0xc7, 0x4b, 0x48, 0x3a, 0xfb, 0x86, 0x0f, + 0xc3, 0xe7, 0x1c, 0xbb, 0xbe, 0x5f, 0xb9, 0x9c, 0xa5, 0x82, 0xf3, 0x48, 0xa3, 0x0a, 0x9c, 0xf1, + 0x83, 0x98, 0x54, 0x3b, 0x11, 0xb9, 0x52, 0x0f, 0xc2, 0x88, 0x5c, 0x0e, 0x63, 0x4a, 0x4e, 0x5c, + 0x3e, 0x56, 0xe1, 0xb6, 0x57, 0xf2, 0x90, 0x70, 0x7e, 0x5d, 0xb4, 0x04, 0x27, 0x6b, 0x7e, 0xec, + 0x6d, 0x36, 0x49, 0xa5, 0xb3, 0xd9, 0x0a, 0xf9, 0xd1, 0x7c, 0x94, 0x11, 0xbc, 0x57, 0xda, 0x91, + 0x16, 0xb2, 0x08, 0xb8, 0xbb, 0x0e, 0x7a, 0x0a, 0xc6, 0x62, 0x3f, 0xa8, 0x37, 0xc9, 0x5c, 0xe4, + 0x05, 0xd5, 0x86, 0xb8, 0xb5, 0xac, 0xec, 0xed, 0x15, 0xad, 0x0c, 0x1b, 0x98, 0x6c, 0xcd, 0xf3, + 0x3a, 0x19, 0x6d, 0x50, 0x60, 0x8b, 0x52, 0x34, 0x0b, 0x27, 0x64, 0x1f, 0x2a, 0xdb, 0x7e, 0x7b, + 0x63, 0xa5, 0xc2, 0xb4, 0xc2, 0x91, 0x34, 0x98, 0xe8, 0x8a, 0x59, 0x8c, 0xb3, 0xf8, 0xee, 0x0f, + 0x1c, 0x18, 0xd3, 0xa3, 0xf5, 0xa9, 0xb2, 0x0e, 0x8d, 0x85, 0xc5, 0x0a, 0xdf, 0x4e, 0xec, 0x29, + 0x0d, 0x97, 0x15, 0xcd, 0xf4, 0xbc, 0x9d, 0xc2, 0xb0, 0xc6, 0xb3, 0x8f, 0x1b, 0xff, 0x0f, 0x41, + 0x71, 0x2b, 0xa4, 0x3a, 0xcd, 0x80, 0x69, 0xeb, 0x5f, 0xa4, 0x40, 0xcc, 0xcb, 0xdc, 0xff, 0xee, + 0xc0, 0xd9, 0xfc, 0x8b, 0x08, 0x3f, 0x0d, 0x9d, 0xbc, 0x08, 0x40, 0xbb, 0x62, 0xec, 0x0b, 0x5a, + 0xce, 0x0f, 0x59, 0x82, 0x35, 0xac, 0xfe, 0xba, 0xfd, 0x6f, 0x0a, 0xa0, 0xf1, 0x44, 0x9f, 0x77, + 0x60, 0x9c, 0xb2, 0x5d, 0x8e, 0x36, 0x8d, 0xde, 0xae, 0xd9, 0xe9, 0xad, 0x22, 0x9b, 0xba, 0x34, + 0x0c, 0x30, 0x36, 0x99, 0xa3, 0x9f, 0x83, 0x51, 0xaf, 0x56, 0x8b, 0x48, 0x1c, 0x2b, 0xe7, 0x20, + 0x33, 0x78, 0xcd, 0x4a, 0x20, 0x4e, 0xcb, 0xa9, 0x1c, 0x6e, 0xd4, 0xb6, 0x62, 0x2a, 0xda, 0x84, + 0xec, 0x57, 0x72, 0x98, 0x32, 0xa1, 0x70, 0xac, 0x30, 0xd0, 0xb3, 0x70, 0xb6, 0xe6, 0x25, 0x1e, + 0x57, 0x01, 0x49, 0xb4, 0x1e, 0x85, 0x09, 0xa9, 0xb2, 0x7d, 0x83, 0xc7, 0x92, 0x9c, 0x17, 0x75, + 0xcf, 0x2e, 0xe4, 0x62, 0xe1, 0x1e, 0xb5, 0xdd, 0x5f, 0x19, 0x04, 0xb3, 0x4f, 0xa8, 0x06, 0x27, + 0xb6, 0xa3, 0xcd, 0x79, 0x16, 0xb3, 0x71, 0x94, 0xd8, 0x09, 0x16, 0xd3, 0xb0, 0x6c, 0x52, 0xc0, + 0x59, 0x92, 0x82, 0xcb, 0x32, 0xd9, 0x4d, 0xbc, 0xcd, 0x23, 0x47, 0x4e, 0x2c, 0x9b, 0x14, 0x70, + 0x96, 0x24, 0x7a, 0x2f, 0x94, 0xb6, 0xa3, 0x4d, 0xb9, 0x7b, 0x64, 0xa3, 0x74, 0x96, 0xd3, 0x22, + 0xac, 0xe3, 0xd1, 0x4f, 0xb3, 0x1d, 0x6d, 0xd2, 0x0d, 0x5b, 0x66, 0xd6, 0x50, 0x9f, 0x66, 0x59, + 0xc0, 0xb1, 0xc2, 0x40, 0x6d, 0x40, 0xdb, 0x72, 0xf4, 0x54, 0x84, 0x8a, 0xd8, 0xe4, 0xfa, 0x0f, + 0x70, 0x61, 0x37, 0x07, 0x96, 0xbb, 0xe8, 0xe0, 0x1c, 0xda, 0xe8, 0x39, 0x38, 0xb7, 0x1d, 0x6d, + 0x0a, 0x3d, 0x66, 0x3d, 0xf2, 0x83, 0xaa, 0xdf, 0x36, 0xb2, 0x68, 0x4c, 0x8b, 0xe6, 0x9e, 0x5b, + 0xce, 0x47, 0xc3, 0xbd, 0xea, 0xbb, 0xbf, 0x33, 0x08, 0xec, 0xfe, 0x2f, 0x15, 0xd3, 0x2d, 0x92, + 0x34, 0xc2, 0x5a, 0x56, 0x35, 0x5b, 0x65, 0x50, 0x2c, 0x4a, 0x65, 0x7c, 0x6c, 0xa1, 0x47, 0x7c, + 0xec, 0x0d, 0x18, 0x6e, 0x10, 0xaf, 0x46, 0x22, 0x69, 0xdc, 0x5c, 0xb1, 0x73, 0x63, 0xf9, 0x32, + 0x23, 0x9a, 0x5a, 0x08, 0xf8, 0xef, 0x18, 0x4b, 0x6e, 0xe8, 0x7d, 0x30, 0x41, 0x75, 0xac, 0xb0, + 0x93, 0x48, 0xff, 0x04, 0x37, 0x6e, 0xb2, 0xcd, 0x7e, 0xc3, 0x28, 0xc1, 0x19, 0x4c, 0xb4, 0x00, + 0x93, 0xc2, 0x97, 0xa0, 0x8c, 0xa6, 0x62, 0x60, 0x55, 0x7a, 0x93, 0x4a, 0xa6, 0x1c, 0x77, 0xd5, + 0x60, 0xf1, 0x8d, 0x61, 0x8d, 0xbb, 0x93, 0xf5, 0xf8, 0xc6, 0xb0, 0xb6, 0x8b, 0x59, 0x09, 0x7a, + 0x19, 0x46, 0xe8, 0xdf, 0xc5, 0x28, 0x6c, 0x09, 0xb3, 0xd1, 0xba, 0x9d, 0xd1, 0xa1, 0x3c, 0xc4, + 0x21, 0x96, 0xe9, 0x9e, 0x73, 0x82, 0x0b, 0x56, 0xfc, 0xe8, 0x51, 0x4a, 0xdf, 0x2e, 0x9f, 0x25, + 0x91, 0xbf, 0xb5, 0xcb, 0xf4, 0x99, 0x91, 0xf4, 0x28, 0x75, 0xa5, 0x0b, 0x03, 0xe7, 0xd4, 0x72, + 0x3f, 0x5f, 0x80, 0x31, 0xfd, 0x1a, 0xf9, 0xed, 0x82, 0xa6, 0xe3, 0x74, 0x52, 0xf0, 0x83, 0xf3, + 0x65, 0x0b, 0xdd, 0xbe, 0xdd, 0x84, 0x68, 0xc0, 0xa0, 0xd7, 0x11, 0x8a, 0xac, 0x15, 0xfb, 0x1c, + 0xeb, 0x71, 0x27, 0x69, 0xf0, 0x9b, 0x7f, 0x2c, 0x9c, 0x99, 0x71, 0x70, 0x3f, 0x3d, 0x00, 0x23, + 0xb2, 0x10, 0x7d, 0xca, 0x01, 0x48, 0xe3, 0xc6, 0x84, 0x28, 0x5d, 0xb7, 0x11, 0x54, 0xa4, 0x87, + 0xbc, 0x69, 0x66, 0x7e, 0x05, 0xc7, 0x1a, 0x5f, 0x94, 0xc0, 0x50, 0x48, 0x1b, 0x77, 0xd1, 0x5e, + 0x2a, 0x84, 0x35, 0xca, 0xf8, 0x22, 0xe3, 0x9e, 0x5a, 0xf4, 0x18, 0x0c, 0x0b, 0x5e, 0xf4, 0x70, + 0xba, 0x29, 0xc3, 0x19, 0xed, 0x59, 0xbf, 0x55, 0x84, 0x64, 0x7a, 0xd6, 0x54, 0x20, 0x9c, 0x32, + 0x74, 0x9f, 0x80, 0x09, 0x73, 0x31, 0xd0, 0xc3, 0xca, 0xe6, 0x6e, 0x42, 0xb8, 0x29, 0x64, 0x8c, + 0x1f, 0x56, 0xe6, 0x28, 0x00, 0x73, 0xb8, 0xfb, 0x7d, 0x07, 0x20, 0x15, 0x2f, 0x7d, 0x78, 0x1f, + 0x1e, 0xd2, 0xed, 0x78, 0xbd, 0x4e, 0x84, 0x1f, 0x87, 0x51, 0xf6, 0x0f, 0x5b, 0xe8, 0x03, 0xb6, + 0x82, 0x0f, 0xd2, 0x76, 0x8a, 0xa5, 0xce, 0x74, 0x8d, 0x67, 0x25, 0x23, 0x9c, 0xf2, 0x74, 0x43, + 0x98, 0xcc, 0x62, 0xa3, 0x0f, 0xc3, 0x58, 0x2c, 0xb7, 0xd5, 0xf4, 0x7a, 0x60, 0x9f, 0xdb, 0x2f, + 0x77, 0xfd, 0x69, 0xd5, 0xb1, 0x41, 0xcc, 0x5d, 0x83, 0x21, 0xab, 0x43, 0xe8, 0x7e, 0xcb, 0x81, + 0x51, 0xe6, 0x7d, 0xad, 0x47, 0x5e, 0x2b, 0xad, 0x32, 0x70, 0xc0, 0xa8, 0xc7, 0x30, 0xcc, 0xcd, + 0x07, 0x32, 0x6a, 0xc9, 0x82, 0x94, 0xe1, 0x19, 0x0c, 0x53, 0x29, 0xc3, 0xed, 0x14, 0x31, 0x96, + 0x9c, 0xdc, 0xcf, 0x14, 0x60, 0xe8, 0x4a, 0xd0, 0xee, 0xfc, 0xa5, 0xcf, 0xa2, 0xb7, 0x0a, 0x83, + 0x57, 0x12, 0xd2, 0x32, 0x93, 0x3d, 0x8e, 0xcd, 0x3d, 0xac, 0x27, 0x7a, 0x2c, 0x9b, 0x89, 0x1e, + 0xb1, 0x77, 0x43, 0x06, 0xf5, 0x09, 0xf3, 0x75, 0x7a, 0x45, 0xf2, 0x71, 0x18, 0x5d, 0xf1, 0x36, + 0x49, 0x73, 0x99, 0xec, 0xb2, 0x0b, 0x8d, 0x3c, 0xc0, 0xc4, 0x49, 0x6d, 0x0e, 0x46, 0x30, 0xc8, + 0x02, 0x4c, 0x30, 0x6c, 0xb5, 0x18, 0xe8, 0x89, 0x84, 0xa4, 0x99, 0xb2, 0x1c, 0xf3, 0x44, 0xa2, + 0x65, 0xc9, 0xd2, 0xb0, 0xdc, 0x19, 0x28, 0xa5, 0x54, 0xfa, 0xe0, 0xfa, 0x93, 0x02, 0x8c, 0x1b, + 0x56, 0x78, 0xc3, 0x37, 0xe9, 0xdc, 0xd6, 0x37, 0x69, 0xf8, 0x0a, 0x0b, 0xef, 0xb4, 0xaf, 0x70, + 0xe0, 0xee, 0xfb, 0x0a, 0xcd, 0x8f, 0x34, 0xd8, 0xd7, 0x47, 0x7a, 0xcb, 0x81, 0xc1, 0x15, 0x3f, + 0xd8, 0xee, 0x4f, 0xd0, 0xc4, 0xd5, 0xb0, 0xdd, 0x25, 0x68, 0x2a, 0x14, 0x88, 0x79, 0x99, 0x54, + 0x5d, 0x06, 0x7a, 0xa8, 0x2e, 0xa9, 0xf3, 0x64, 0xf0, 0x20, 0xe7, 0x89, 0xfb, 0x29, 0x07, 0xc6, + 0x56, 0xbd, 0xc0, 0xdf, 0x22, 0x71, 0xc2, 0x26, 0x60, 0x72, 0xac, 0x37, 0xe0, 0xc6, 0x7a, 0xe4, + 0x92, 0x78, 0xc3, 0x81, 0x93, 0xab, 0xa4, 0x15, 0xfa, 0x2f, 0x7b, 0x69, 0x70, 0x2d, 0xed, 0x63, + 0xc3, 0x4f, 0x44, 0x2c, 0xa1, 0xea, 0xe3, 0x65, 0x3f, 0xc1, 0x14, 0x7e, 0x1b, 0x5b, 0x34, 0xbb, + 0x5b, 0x42, 0x4f, 0x72, 0xda, 0xad, 0xcc, 0x34, 0x6c, 0x56, 0x16, 0xe0, 0x14, 0xc7, 0xfd, 0x5d, + 0x07, 0x86, 0x79, 0x23, 0x54, 0x3c, 0xb2, 0xd3, 0x83, 0x76, 0x03, 0x8a, 0xac, 0x9e, 0x98, 0xfe, + 0x4b, 0x16, 0xf4, 0x24, 0x4a, 0x8e, 0x2f, 0x56, 0xf6, 0x2f, 0xe6, 0x0c, 0xd8, 0xf9, 0xc6, 0xbb, + 0x39, 0xab, 0xe2, 0x8a, 0xd3, 0xf3, 0x0d, 0x83, 0x62, 0x51, 0xea, 0x7e, 0x6d, 0x00, 0x46, 0x54, + 0xe2, 0x36, 0x96, 0xe0, 0x22, 0x08, 0xc2, 0xc4, 0xe3, 0xf1, 0x1a, 0x5c, 0xa8, 0x7f, 0xd8, 0x5e, + 0xe2, 0xb8, 0x99, 0xd9, 0x94, 0x3a, 0xf7, 0x41, 0xaa, 0xd3, 0xaa, 0x56, 0x82, 0xf5, 0x46, 0xa0, + 0xd7, 0x61, 0xa8, 0x49, 0xc5, 0x94, 0x94, 0xf1, 0xcf, 0x5a, 0x6c, 0x0e, 0x93, 0x7f, 0xa2, 0x25, + 0x6a, 0x84, 0x38, 0x10, 0x0b, 0xae, 0x53, 0x1f, 0x80, 0xc9, 0x6c, 0xab, 0x6f, 0x77, 0x69, 0x74, + 0x54, 0xbf, 0x72, 0xfa, 0xd7, 0x84, 0x98, 0x3d, 0x7c, 0x55, 0xf7, 0x19, 0x28, 0xad, 0x92, 0x24, + 0xf2, 0xab, 0x8c, 0xc0, 0xed, 0x26, 0x57, 0x5f, 0x8a, 0xc6, 0x67, 0xd9, 0x64, 0xa5, 0x34, 0x63, + 0xf4, 0x2a, 0x40, 0x3b, 0x0a, 0xe9, 0x41, 0x97, 0x74, 0xe4, 0xc7, 0xb6, 0xa0, 0x38, 0xaf, 0x2b, + 0x9a, 0xdc, 0x6d, 0x9e, 0xfe, 0xc6, 0x1a, 0x3f, 0xf7, 0x4d, 0x07, 0x8a, 0xab, 0x9d, 0x84, 0xdc, + 0xec, 0x43, 0xb4, 0x1d, 0x3a, 0x8d, 0xc2, 0xe3, 0x30, 0x42, 0x3f, 0xf0, 0xa6, 0x17, 0x4b, 0x83, + 0x5b, 0x1a, 0x76, 0x2e, 0xe0, 0x58, 0x61, 0xb8, 0x1f, 0x86, 0x31, 0xd6, 0x92, 0xcb, 0x61, 0x93, + 0x6e, 0xd7, 0x74, 0x24, 0x5b, 0xf4, 0x77, 0xd6, 0x0f, 0xc2, 0x90, 0x30, 0x2f, 0xa3, 0x2b, 0xac, + 0x11, 0x36, 0x6b, 0xea, 0x02, 0x9a, 0x9a, 0x3f, 0x97, 0x19, 0x14, 0x8b, 0x52, 0xf7, 0x93, 0x05, + 0x28, 0xb1, 0x8a, 0x42, 0x3a, 0xed, 0xc2, 0x70, 0x83, 0xf3, 0x11, 0x43, 0x6e, 0x21, 0x6e, 0x4d, + 0x6f, 0xbd, 0x76, 0x46, 0xe4, 0x00, 0x2c, 0xf9, 0x51, 0xd6, 0x37, 0x3c, 0x3f, 0xa1, 0xac, 0x0b, + 0xc7, 0xcb, 0xfa, 0x3a, 0x67, 0x83, 0x25, 0x3f, 0xf7, 0x97, 0x80, 0x5d, 0xec, 0x5e, 0x6c, 0x7a, + 0x75, 0x3e, 0x72, 0xe1, 0x36, 0xa9, 0x09, 0x11, 0xad, 0x8d, 0x1c, 0x85, 0x62, 0x51, 0xca, 0x2f, + 0xcb, 0x26, 0x91, 0xaf, 0x22, 0xbe, 0xb5, 0xcb, 0xb2, 0x0c, 0x2c, 0xe3, 0xfb, 0x6b, 0xee, 0x97, + 0x0a, 0x00, 0x2c, 0x2b, 0x20, 0xbf, 0x8f, 0xfd, 0xf3, 0x32, 0x38, 0xcb, 0xf4, 0x9d, 0xaa, 0xe0, + 0x2c, 0x76, 0xe3, 0x5c, 0x0f, 0xca, 0xd2, 0x2f, 0x62, 0x14, 0x0e, 0xbe, 0x88, 0x81, 0xda, 0x30, + 0x1c, 0x76, 0x12, 0xaa, 0x03, 0x0b, 0x25, 0xc2, 0x42, 0xe8, 0xc0, 0x1a, 0x27, 0xc8, 0x6f, 0x2f, + 0x88, 0x1f, 0x58, 0xb2, 0x41, 0x4f, 0xc1, 0x48, 0x3b, 0x0a, 0xeb, 0x54, 0x27, 0x10, 0xfb, 0xf2, + 0xfd, 0x72, 0x36, 0xaf, 0x0b, 0xf8, 0x2d, 0xed, 0x7f, 0xac, 0xb0, 0xdd, 0xbf, 0x77, 0x92, 0x8f, + 0x8b, 0x98, 0x7b, 0x53, 0x50, 0xf0, 0xa5, 0xc5, 0x0b, 0x04, 0x89, 0xc2, 0x95, 0x05, 0x5c, 0xf0, + 0x6b, 0x6a, 0x15, 0x16, 0x7a, 0xae, 0xc2, 0xf7, 0x42, 0xa9, 0xe6, 0xc7, 0xed, 0xa6, 0xb7, 0x7b, + 0x35, 0xc7, 0xdc, 0xb8, 0x90, 0x16, 0x61, 0x1d, 0x0f, 0x3d, 0x2e, 0xae, 0xdd, 0x0c, 0x1a, 0x26, + 0x26, 0x79, 0xed, 0x26, 0xbd, 0xef, 0xcf, 0x6f, 0xdc, 0x64, 0xf3, 0x22, 0x14, 0xfb, 0xce, 0x8b, + 0x90, 0xd5, 0xf0, 0x86, 0xee, 0xbe, 0x86, 0xf7, 0x7e, 0x18, 0x97, 0x3f, 0x99, 0xd6, 0x55, 0x3e, + 0xcd, 0x5a, 0xaf, 0xcc, 0xeb, 0x1b, 0x7a, 0x21, 0x36, 0x71, 0xd3, 0x49, 0x3b, 0xdc, 0xef, 0xa4, + 0xbd, 0x08, 0xb0, 0x19, 0x76, 0x82, 0x9a, 0x17, 0xed, 0x5e, 0x59, 0x10, 0x41, 0xba, 0x4a, 0xa1, + 0x9c, 0x53, 0x25, 0x58, 0xc3, 0xd2, 0x27, 0xfa, 0xe8, 0x6d, 0x26, 0xfa, 0x87, 0x61, 0x94, 0x05, + 0x34, 0x93, 0xda, 0x6c, 0x22, 0xa2, 0xaa, 0x0e, 0x13, 0x25, 0x9a, 0xc6, 0x59, 0x4a, 0x22, 0x38, + 0xa5, 0x87, 0x3e, 0x02, 0xb0, 0xe5, 0x07, 0x7e, 0xdc, 0x60, 0xd4, 0x4b, 0x87, 0xa6, 0xae, 0xfa, + 0xb9, 0xa8, 0xa8, 0x60, 0x8d, 0x22, 0x7a, 0x01, 0x4e, 0x92, 0x38, 0xf1, 0x5b, 0x5e, 0x42, 0x6a, + 0xea, 0x1e, 0x6b, 0x99, 0xd9, 0x48, 0x55, 0x48, 0xf9, 0xa5, 0x2c, 0xc2, 0xad, 0x3c, 0x20, 0xee, + 0x26, 0x64, 0xac, 0xc8, 0xa9, 0xc3, 0xac, 0x48, 0xf4, 0xbf, 0x1c, 0x38, 0x19, 0x11, 0x1e, 0x6a, + 0x13, 0xab, 0x86, 0x9d, 0x61, 0xe2, 0xb8, 0x6a, 0x23, 0xe1, 0xbe, 0xca, 0x31, 0x83, 0xb3, 0x5c, + 0xb8, 0x9e, 0x43, 0x64, 0xef, 0xbb, 0xca, 0x6f, 0xe5, 0x01, 0xdf, 0x78, 0x7b, 0x7a, 0xba, 0xfb, + 0xe1, 0x07, 0x45, 0x9c, 0xae, 0xbc, 0xbf, 0xf5, 0xf6, 0xf4, 0xa4, 0xfc, 0x9d, 0x0e, 0x5a, 0x57, + 0x27, 0xe9, 0xb6, 0xda, 0x0e, 0x6b, 0x57, 0xd6, 0x45, 0xf8, 0x9b, 0xda, 0x56, 0xd7, 0x29, 0x10, + 0xf3, 0x32, 0xf4, 0x28, 0xdd, 0xb9, 0x49, 0x2b, 0x0c, 0x54, 0xea, 0xe4, 0x31, 0xbe, 0x6b, 0x73, + 0x18, 0x56, 0xa5, 0xf4, 0xc8, 0x11, 0x88, 0x2d, 0xa5, 0x7c, 0x9f, 0xad, 0x23, 0x87, 0xdc, 0xa4, + 0x38, 0x57, 0xf9, 0x0b, 0x2b, 0x4e, 0xa8, 0x09, 0x43, 0x3e, 0x33, 0x80, 0x88, 0x08, 0x5b, 0x0b, + 0x56, 0x17, 0x6e, 0x50, 0x91, 0xf1, 0xb5, 0x4c, 0xf4, 0x0b, 0x1e, 0xfa, 0x5e, 0x73, 0xe2, 0xee, + 0xec, 0x35, 0x8f, 0xc2, 0x48, 0xb5, 0xe1, 0x37, 0x6b, 0x11, 0x09, 0xca, 0x93, 0xcc, 0x12, 0xc0, + 0x46, 0x62, 0x5e, 0xc0, 0xb0, 0x2a, 0x45, 0x7f, 0x15, 0xc6, 0xc3, 0x4e, 0xc2, 0x44, 0x0b, 0x1d, + 0xa7, 0xb8, 0x7c, 0x92, 0xa1, 0xb3, 0x78, 0xa9, 0x35, 0xbd, 0x00, 0x9b, 0x78, 0x54, 0xc4, 0x37, + 0xc2, 0x98, 0xa5, 0x43, 0x62, 0x22, 0xfe, 0xac, 0x29, 0xe2, 0x2f, 0x6b, 0x65, 0xd8, 0xc0, 0x44, + 0x5f, 0x71, 0xe0, 0x64, 0x2b, 0x7b, 0xde, 0x2b, 0x9f, 0x63, 0x23, 0x53, 0xb1, 0x71, 0x2e, 0xc8, + 0x90, 0xe6, 0x91, 0xee, 0x5d, 0x60, 0xdc, 0xdd, 0x08, 0x96, 0x98, 0x2c, 0xde, 0x0d, 0xaa, 0x8d, + 0x28, 0x0c, 0xcc, 0xe6, 0xdd, 0x6b, 0xeb, 0xbe, 0x1d, 0x5b, 0xdb, 0x79, 0x2c, 0xe6, 0xee, 0xdd, + 0xdf, 0x9b, 0x3e, 0x93, 0x5b, 0x84, 0xf3, 0x1b, 0x85, 0x3e, 0x04, 0x93, 0x89, 0x17, 0x6f, 0x73, + 0x7d, 0x89, 0xd6, 0x24, 0xb5, 0xf2, 0xfd, 0x3c, 0xc8, 0x61, 0x7f, 0x6f, 0x7a, 0x72, 0x23, 0x53, + 0x86, 0xbb, 0xb0, 0xa7, 0x16, 0xe0, 0x6c, 0xbe, 0x84, 0xb9, 0xdd, 0x11, 0x67, 0x40, 0x3f, 0xe2, + 0x2c, 0xc2, 0xbd, 0x3d, 0xbb, 0x45, 0xf7, 0x2a, 0xa9, 0xaf, 0x3a, 0xe6, 0x5e, 0xd5, 0xa5, 0x5f, + 0x4e, 0xc0, 0x98, 0xfe, 0xd6, 0x88, 0xfb, 0x7f, 0x07, 0x00, 0x52, 0x0b, 0x3e, 0xf2, 0x60, 0x82, + 0x7b, 0x0b, 0xae, 0x2c, 0x1c, 0x39, 0xd7, 0xc0, 0xbc, 0x41, 0x00, 0x67, 0x08, 0xa2, 0x16, 0x20, + 0x0e, 0xe1, 0xbf, 0x8f, 0xe2, 0xf5, 0x65, 0x4e, 0xd2, 0xf9, 0x2e, 0x22, 0x38, 0x87, 0x30, 0xed, + 0x51, 0x12, 0x6e, 0x93, 0xe0, 0x1a, 0x5e, 0x39, 0x4a, 0x3e, 0x0b, 0xee, 0x27, 0x34, 0x08, 0xe0, + 0x0c, 0x41, 0xe4, 0xc2, 0x10, 0x33, 0x1a, 0xc9, 0xa8, 0x76, 0x26, 0xa0, 0x98, 0xae, 0x12, 0x63, + 0x51, 0x82, 0xbe, 0xe4, 0xc0, 0x84, 0x4c, 0xcb, 0xc1, 0xec, 0xb4, 0x32, 0x9e, 0xfd, 0x9a, 0x2d, + 0x0f, 0xcc, 0x25, 0x9d, 0x7a, 0x1a, 0x2d, 0x6a, 0x80, 0x63, 0x9c, 0x69, 0x84, 0xfb, 0x1c, 0x9c, + 0xca, 0xa9, 0x6e, 0xe5, 0x08, 0xfd, 0x1d, 0x07, 0x4a, 0x5a, 0xb6, 0x4a, 0xf4, 0x2a, 0x8c, 0x86, + 0x15, 0xeb, 0x21, 0x8a, 0x6b, 0x95, 0xae, 0x10, 0x45, 0x05, 0xc2, 0x29, 0xc3, 0x7e, 0x22, 0x2b, + 0x73, 0x53, 0x6b, 0xbe, 0xc3, 0xcd, 0x3e, 0x74, 0x64, 0xe5, 0xaf, 0x14, 0x21, 0xa5, 0x74, 0xc8, + 0x74, 0x31, 0x69, 0x1c, 0x66, 0xe1, 0xc0, 0x38, 0xcc, 0x1a, 0x9c, 0xf0, 0x98, 0x97, 0xfb, 0x88, + 0x49, 0x62, 0x78, 0xb2, 0x62, 0x93, 0x02, 0xce, 0x92, 0xa4, 0x5c, 0xe2, 0xb4, 0x2a, 0xe3, 0x32, + 0x78, 0x68, 0x2e, 0x15, 0x93, 0x02, 0xce, 0x92, 0x44, 0x2f, 0x40, 0xb9, 0xca, 0x6e, 0x35, 0xf3, + 0x3e, 0x5e, 0xd9, 0xba, 0x1a, 0x26, 0xeb, 0x11, 0x89, 0x49, 0x90, 0x88, 0x74, 0x70, 0x0f, 0x8a, + 0x51, 0x28, 0xcf, 0xf7, 0xc0, 0xc3, 0x3d, 0x29, 0xd0, 0x83, 0x0e, 0x73, 0x93, 0xfb, 0xc9, 0x2e, + 0x13, 0x22, 0x22, 0x7e, 0x40, 0x1d, 0x74, 0x2a, 0x7a, 0x21, 0x36, 0x71, 0xd1, 0x2f, 0x3b, 0x30, + 0xde, 0x94, 0x8e, 0x04, 0xdc, 0x69, 0xca, 0xdc, 0xaa, 0xd8, 0xca, 0xf4, 0x5b, 0xd1, 0x29, 0x73, + 0x6d, 0xc4, 0x00, 0x61, 0x93, 0x77, 0x36, 0x63, 0xcf, 0x48, 0x9f, 0x19, 0x7b, 0xbe, 0xef, 0xc0, + 0x64, 0x96, 0x1b, 0xda, 0x86, 0x07, 0x5a, 0x5e, 0xb4, 0x7d, 0x25, 0xd8, 0x8a, 0xd8, 0xed, 0x95, + 0x84, 0x4f, 0x86, 0xd9, 0xad, 0x84, 0x44, 0x0b, 0xde, 0x2e, 0x77, 0xcc, 0x16, 0xd5, 0x93, 0x60, + 0x0f, 0xac, 0x1e, 0x84, 0x8c, 0x0f, 0xa6, 0x85, 0x2a, 0x70, 0x86, 0x22, 0xb0, 0x84, 0x7e, 0x7e, + 0x18, 0xa4, 0x4c, 0x0a, 0x8c, 0x89, 0x8a, 0xa0, 0x5c, 0xcd, 0x43, 0xc2, 0xf9, 0x75, 0xdd, 0x4b, + 0x30, 0xc4, 0x2f, 0x13, 0xde, 0x91, 0x67, 0xcb, 0xfd, 0xf7, 0x05, 0x90, 0xaa, 0xe5, 0x5f, 0x6e, + 0x47, 0x21, 0xdd, 0x44, 0x23, 0xa6, 0x36, 0x09, 0x7b, 0x09, 0xdb, 0x44, 0x45, 0xea, 0x4c, 0x51, + 0x42, 0x75, 0x6e, 0x72, 0xd3, 0x4f, 0xe6, 0xc3, 0x9a, 0xb4, 0x92, 0x30, 0x9d, 0xfb, 0x92, 0x80, + 0x61, 0x55, 0xea, 0x7e, 0xca, 0x81, 0x71, 0xda, 0xcb, 0x66, 0x93, 0x34, 0x2b, 0x09, 0x69, 0xc7, + 0x28, 0x86, 0x62, 0x4c, 0xff, 0xb1, 0x67, 0x4c, 0x4c, 0x2f, 0xa0, 0x92, 0xb6, 0xe6, 0x45, 0xa2, + 0x4c, 0x30, 0xe7, 0xe5, 0x7e, 0x7b, 0x00, 0x46, 0xd5, 0x60, 0xf7, 0x61, 0xbf, 0xbd, 0x98, 0x66, + 0xb5, 0xe5, 0x12, 0xb8, 0xac, 0x65, 0xb4, 0xbd, 0x45, 0x87, 0x2e, 0xd8, 0xe5, 0xf9, 0x3b, 0xd2, + 0xf4, 0xb6, 0x8f, 0x9b, 0x4e, 0xf0, 0xb3, 0xfa, 0xfc, 0xd3, 0xf0, 0x85, 0x37, 0xfc, 0xa6, 0x1e, + 0x83, 0x30, 0x68, 0x6b, 0x37, 0x53, 0x0e, 0xd6, 0xde, 0xc1, 0x07, 0x99, 0x67, 0x9e, 0x8a, 0x7d, + 0x3d, 0xf3, 0xf4, 0x18, 0x0c, 0x92, 0xa0, 0xd3, 0x62, 0xaa, 0xd2, 0x28, 0x3b, 0x64, 0x0c, 0x5e, + 0x0a, 0x3a, 0x2d, 0xb3, 0x67, 0x0c, 0x05, 0x7d, 0x00, 0x4a, 0x35, 0x12, 0x57, 0x23, 0x9f, 0x25, + 0xa5, 0x10, 0xb6, 0xa1, 0xfb, 0x99, 0xc1, 0x2d, 0x05, 0x9b, 0x15, 0xf5, 0x0a, 0xee, 0xcb, 0x20, + 0xb2, 0x3a, 0xa3, 0x36, 0x0c, 0xf1, 0x14, 0x15, 0x62, 0xb7, 0xb7, 0x70, 0x72, 0xe5, 0xa2, 0x42, + 0x8b, 0x8f, 0xe1, 0xf7, 0x90, 0x05, 0x1f, 0xf7, 0x8d, 0x02, 0x4c, 0x98, 0x09, 0xa7, 0xd1, 0x2f, + 0x18, 0x73, 0xc5, 0xd5, 0xe7, 0x8a, 0xfe, 0xac, 0x11, 0xaf, 0xa5, 0xcd, 0xa0, 0xf7, 0xc3, 0x38, + 0xcf, 0x89, 0x25, 0x2d, 0x26, 0x05, 0x73, 0xc3, 0x99, 0xd7, 0x0b, 0xb1, 0x89, 0xcb, 0xf6, 0xc2, + 0x30, 0x08, 0x78, 0x4c, 0xa8, 0x19, 0x1c, 0x27, 0x1e, 0x1e, 0x4b, 0xf7, 0xc2, 0x1e, 0x78, 0xb8, + 0x27, 0x05, 0xa9, 0x81, 0x0d, 0xf6, 0xd0, 0xc0, 0xfe, 0x85, 0x03, 0xe5, 0x5e, 0x59, 0xb7, 0x8f, + 0x3c, 0x1c, 0x87, 0x55, 0x9f, 0xba, 0xc7, 0x6f, 0xa0, 0xff, 0xf1, 0x73, 0x3f, 0x59, 0x80, 0xe2, + 0x7a, 0x58, 0x5b, 0x9a, 0x47, 0x7f, 0xa3, 0xeb, 0x75, 0xaa, 0x9f, 0xc9, 0x79, 0x9d, 0x6a, 0x9c, + 0x21, 0xe7, 0x3c, 0x4c, 0xd5, 0x84, 0x71, 0xe6, 0x55, 0x93, 0xba, 0x8c, 0x38, 0x1e, 0x3d, 0xd9, + 0x67, 0x76, 0x0e, 0xbd, 0xaa, 0xd8, 0xd9, 0x75, 0x10, 0x36, 0x89, 0xa3, 0x55, 0x38, 0xc5, 0x93, + 0xdc, 0x2e, 0x90, 0xa6, 0xb7, 0x9b, 0x49, 0x66, 0x77, 0x9f, 0x7c, 0x70, 0x70, 0xa1, 0x1b, 0x05, + 0xe7, 0xd5, 0x73, 0x7f, 0x6f, 0x10, 0x34, 0x5f, 0x56, 0x1f, 0x52, 0xef, 0xa5, 0x8c, 0xe7, 0x72, + 0xd5, 0x8a, 0xe7, 0x52, 0xba, 0x03, 0xf9, 0x4e, 0x62, 0x3a, 0x2b, 0x69, 0xa3, 0x1a, 0xa4, 0xd9, + 0x16, 0x7d, 0x54, 0x8d, 0xba, 0x4c, 0x9a, 0x6d, 0xcc, 0x4a, 0xd4, 0x6d, 0xda, 0xc1, 0x9e, 0xb7, + 0x69, 0x1b, 0x50, 0xac, 0x7b, 0x9d, 0x3a, 0x11, 0x31, 0xbe, 0x16, 0x9c, 0xd4, 0xec, 0x7e, 0x0f, + 0x77, 0x52, 0xb3, 0x7f, 0x31, 0x67, 0x40, 0x85, 0x76, 0x43, 0x06, 0x3d, 0x09, 0x73, 0xbd, 0x05, + 0xa1, 0xad, 0xe2, 0xa8, 0xb8, 0xd0, 0x56, 0x3f, 0x71, 0xca, 0x0c, 0xb5, 0x61, 0xb8, 0xca, 0x73, + 0x04, 0x09, 0xdd, 0xf3, 0x8a, 0x8d, 0xeb, 0xc2, 0x8c, 0x20, 0xb7, 0xab, 0x89, 0x1f, 0x58, 0xb2, + 0x71, 0x2f, 0x40, 0x49, 0x7b, 0x24, 0x87, 0x7e, 0x06, 0x95, 0x9e, 0x46, 0xfb, 0x0c, 0x0b, 0x5e, + 0xe2, 0x61, 0x56, 0xe2, 0x7e, 0x63, 0x10, 0x94, 0x55, 0x55, 0xbf, 0xdc, 0xea, 0x55, 0xb5, 0x64, + 0x5a, 0x46, 0xa2, 0x87, 0x30, 0xc0, 0xa2, 0x94, 0x2e, 0xf7, 0x16, 0x89, 0xea, 0xca, 0x1e, 0x92, + 0x15, 0x97, 0xab, 0x7a, 0x21, 0x36, 0x71, 0xe9, 0xe1, 0xaa, 0x25, 0x62, 0x3b, 0xb2, 0xa1, 0xfb, + 0x32, 0xe6, 0x03, 0x2b, 0x0c, 0x96, 0x8d, 0xa3, 0xa5, 0x85, 0x82, 0x88, 0x50, 0x5f, 0x1b, 0xae, + 0x45, 0x8d, 0x2a, 0x0f, 0xc9, 0xd3, 0x21, 0xd8, 0xe0, 0x8a, 0x96, 0xe0, 0x64, 0x4c, 0x92, 0xb5, + 0x1b, 0x01, 0x89, 0x54, 0x1e, 0x0c, 0x91, 0xee, 0x45, 0x5d, 0xfd, 0xa9, 0x64, 0x11, 0x70, 0x77, + 0x9d, 0xdc, 0xe8, 0xe8, 0xe2, 0xa1, 0xa3, 0xa3, 0x17, 0x60, 0x72, 0xcb, 0xf3, 0x9b, 0x9d, 0x88, + 0xf4, 0x8c, 0xb1, 0x5e, 0xcc, 0x94, 0xe3, 0xae, 0x1a, 0xec, 0xf6, 0x59, 0xd3, 0xab, 0xc7, 0xe5, + 0x61, 0xed, 0xf6, 0x19, 0x05, 0x60, 0x0e, 0x77, 0x7f, 0xcb, 0x01, 0x9e, 0x67, 0x6b, 0x76, 0x6b, + 0xcb, 0x0f, 0xfc, 0x64, 0x17, 0x7d, 0xd5, 0x81, 0xc9, 0x20, 0xac, 0x91, 0xd9, 0x20, 0xf1, 0x25, + 0xd0, 0xde, 0xdb, 0x08, 0x8c, 0xd7, 0xd5, 0x0c, 0x79, 0x6e, 0x32, 0xcc, 0x42, 0x71, 0x57, 0x33, + 0xdc, 0x73, 0x70, 0x26, 0x97, 0x80, 0xfb, 0xfd, 0x01, 0x30, 0xd3, 0x85, 0xa1, 0x67, 0xa0, 0xd8, + 0x64, 0x09, 0x6c, 0x9c, 0x23, 0xe6, 0x81, 0x63, 0x63, 0xc5, 0x33, 0xdc, 0x70, 0x4a, 0x68, 0x01, + 0x4a, 0x2c, 0x07, 0x99, 0x48, 0x2f, 0x54, 0x30, 0xb6, 0xdc, 0x12, 0x4e, 0x8b, 0x6e, 0x99, 0x3f, + 0xb1, 0x5e, 0x0d, 0xbd, 0x02, 0xc3, 0x9b, 0x3c, 0x51, 0xab, 0x3d, 0xef, 0xaf, 0xc8, 0xfc, 0xca, + 0x74, 0x5c, 0x99, 0x06, 0xf6, 0x56, 0xfa, 0x2f, 0x96, 0x1c, 0xd1, 0x2e, 0x8c, 0x78, 0xf2, 0x9b, + 0x0e, 0xda, 0xba, 0x0a, 0x64, 0xcc, 0x1f, 0x11, 0x6a, 0x25, 0xbf, 0xa1, 0x62, 0x97, 0x09, 0x5e, + 0x2b, 0xf6, 0x15, 0xbc, 0xf6, 0x2d, 0x07, 0x20, 0x7d, 0x55, 0x07, 0xdd, 0x84, 0x91, 0xf8, 0x49, + 0xc3, 0xe0, 0x64, 0x23, 0x8d, 0x84, 0xa0, 0xa8, 0x5d, 0xb5, 0x16, 0x10, 0xac, 0xb8, 0xdd, 0xce, + 0x48, 0xf6, 0x13, 0x07, 0x4e, 0xe7, 0xbd, 0xfe, 0xf3, 0x0e, 0xb6, 0xf8, 0xd0, 0x0a, 0x1e, 0xaf, + 0xb0, 0x1e, 0x91, 0x2d, 0xff, 0x66, 0x4e, 0xba, 0x70, 0x5e, 0x80, 0x53, 0x1c, 0xf7, 0x4f, 0x87, + 0x41, 0x31, 0x3e, 0x26, 0x7b, 0xda, 0x23, 0xf4, 0xec, 0x5b, 0x4f, 0x75, 0x2e, 0x85, 0x87, 0x19, + 0x14, 0x8b, 0x52, 0x7a, 0xfe, 0x95, 0xd7, 0x2e, 0x84, 0xc8, 0x66, 0xb3, 0x50, 0x5e, 0xcf, 0xc0, + 0xaa, 0x34, 0xcf, 0x42, 0x57, 0xbc, 0x2b, 0x16, 0xba, 0x21, 0xfb, 0x16, 0xba, 0x16, 0xa0, 0x98, + 0x2f, 0x14, 0x66, 0x16, 0x13, 0x8c, 0xc6, 0x0e, 0xed, 0x30, 0xa8, 0x74, 0x11, 0xc1, 0x39, 0x84, + 0x59, 0x34, 0x4d, 0xd8, 0x24, 0xb3, 0xf8, 0xaa, 0x38, 0x44, 0xa6, 0xd1, 0x34, 0x1c, 0x8c, 0x65, + 0xf9, 0x11, 0x4d, 0x62, 0xe8, 0xb7, 0x9d, 0x03, 0x6c, 0x8e, 0xa3, 0xb6, 0xb6, 0xa0, 0xdc, 0x5c, + 0x8d, 0xec, 0x44, 0x7c, 0x14, 0x43, 0xe6, 0xd7, 0x1c, 0x38, 0x49, 0x82, 0x6a, 0xb4, 0xcb, 0xe8, + 0x08, 0x6a, 0x22, 0xd8, 0xe1, 0x9a, 0x8d, 0xb5, 0x7e, 0x29, 0x4b, 0x9c, 0xfb, 0x14, 0xbb, 0xc0, + 0xb8, 0xbb, 0x19, 0x68, 0x0d, 0x46, 0xaa, 0x9e, 0x98, 0x17, 0xa5, 0xc3, 0xcc, 0x0b, 0xee, 0xb2, + 0x9d, 0x15, 0xb3, 0x41, 0x11, 0x71, 0x7f, 0x54, 0x80, 0x53, 0x39, 0x4d, 0x62, 0x37, 0x02, 0x5b, + 0x74, 0x01, 0x5c, 0xa9, 0x65, 0x97, 0xff, 0xb2, 0x80, 0x63, 0x85, 0x81, 0xd6, 0xe1, 0xf4, 0x76, + 0x2b, 0x4e, 0xa9, 0xcc, 0x87, 0x41, 0x42, 0x6e, 0x4a, 0x61, 0x20, 0x03, 0x21, 0x4e, 0x2f, 0xe7, + 0xe0, 0xe0, 0xdc, 0x9a, 0x54, 0x5b, 0x22, 0x81, 0xb7, 0xd9, 0x24, 0x69, 0x91, 0x08, 0xdb, 0x53, + 0xda, 0xd2, 0xa5, 0x4c, 0x39, 0xee, 0xaa, 0x81, 0xde, 0x74, 0xe0, 0xbe, 0x98, 0x44, 0x3b, 0x24, + 0xaa, 0xf8, 0x35, 0x32, 0xdf, 0x89, 0x93, 0xb0, 0x45, 0xa2, 0x23, 0x5a, 0xd9, 0xa7, 0xf7, 0xf7, + 0xa6, 0xef, 0xab, 0xf4, 0xa6, 0x86, 0x0f, 0x62, 0xe5, 0xbe, 0xe9, 0xc0, 0x44, 0x85, 0xd9, 0x60, + 0x94, 0xea, 0x6e, 0x3b, 0x5b, 0xef, 0x23, 0x2a, 0x39, 0x4c, 0x46, 0x08, 0x9b, 0xe9, 0x5c, 0xdc, + 0x17, 0x61, 0xb2, 0x42, 0x5a, 0x5e, 0xbb, 0xc1, 0xee, 0xc9, 0xf3, 0x40, 0xc0, 0x0b, 0x30, 0x1a, + 0x4b, 0x58, 0xf6, 0xfd, 0x2e, 0x85, 0x8c, 0x53, 0x1c, 0xf4, 0x30, 0x0f, 0x5a, 0x94, 0x57, 0xda, + 0x46, 0xf9, 0x21, 0x87, 0x47, 0x3a, 0xc6, 0x58, 0x96, 0xb9, 0xdf, 0x2a, 0xc0, 0x58, 0x5a, 0x9f, + 0x6c, 0xa1, 0x3a, 0x9c, 0xa8, 0x6a, 0xd7, 0x41, 0xd3, 0x8b, 0x38, 0xfd, 0xdf, 0x1c, 0xe5, 0x49, + 0xc4, 0x4d, 0x22, 0x38, 0x4b, 0xf5, 0xf0, 0x11, 0xa2, 0xaf, 0x64, 0x22, 0x44, 0xad, 0x3c, 0x0c, + 0x52, 0xd9, 0x0d, 0xaa, 0x2a, 0xbe, 0x94, 0x6c, 0xc9, 0xd0, 0x95, 0xae, 0x80, 0xd3, 0x2f, 0x14, + 0xe0, 0x84, 0x1a, 0x27, 0xe1, 0xec, 0x7e, 0x2d, 0x1b, 0x17, 0x8a, 0x6d, 0xe4, 0xd8, 0x32, 0x3f, + 0xfc, 0x01, 0xb1, 0xa1, 0xaf, 0x65, 0x63, 0x43, 0x8f, 0x95, 0x7d, 0x97, 0xff, 0xfe, 0x5b, 0x05, + 0x18, 0x51, 0x19, 0xbf, 0x9e, 0x81, 0x22, 0x3b, 0x36, 0xdf, 0x99, 0xf2, 0xcf, 0x8e, 0xe0, 0x98, + 0x53, 0xa2, 0x24, 0x59, 0xec, 0xd9, 0x91, 0xf3, 0x4a, 0x8f, 0x72, 0x23, 0xb8, 0x17, 0x25, 0x98, + 0x53, 0x42, 0xcb, 0x30, 0x40, 0x82, 0x9a, 0x98, 0x3c, 0x87, 0x27, 0xc8, 0x9e, 0x19, 0xbc, 0x14, + 0xd4, 0x30, 0xa5, 0xc2, 0xd2, 0x0e, 0x72, 0x65, 0x2f, 0x73, 0xf1, 0x42, 0x68, 0x7a, 0xa2, 0xd4, + 0x9d, 0x03, 0x23, 0x25, 0xe5, 0x91, 0x2e, 0xfe, 0xfc, 0xf2, 0x00, 0x0c, 0x55, 0x3a, 0x9b, 0xf4, + 0x4c, 0xf4, 0x4d, 0x07, 0x4e, 0xdd, 0xc8, 0x24, 0x6e, 0x4f, 0x17, 0xe9, 0x35, 0x7b, 0xce, 0x04, + 0x3d, 0x86, 0x52, 0x99, 0xde, 0x72, 0x0a, 0x71, 0x5e, 0x73, 0x8c, 0xdc, 0xc9, 0x03, 0xc7, 0x92, + 0x3b, 0xf9, 0xe6, 0x31, 0x5f, 0x4e, 0x1a, 0xef, 0x75, 0x31, 0xc9, 0xfd, 0xbd, 0x22, 0x00, 0xff, + 0x1a, 0x6b, 0xed, 0xa4, 0x1f, 0xb3, 0xe2, 0x53, 0x30, 0x56, 0x27, 0x01, 0x89, 0x64, 0x84, 0x6c, + 0xe6, 0xcd, 0xb1, 0x25, 0xad, 0x0c, 0x1b, 0x98, 0x6c, 0xb2, 0x04, 0x49, 0xb4, 0xcb, 0xf5, 0xfc, + 0xec, 0x05, 0x24, 0x55, 0x82, 0x35, 0x2c, 0x34, 0x63, 0x78, 0xef, 0x78, 0x20, 0xc8, 0xc4, 0x01, + 0xce, 0xb6, 0x0f, 0xc0, 0x84, 0x99, 0x68, 0x48, 0x68, 0x9b, 0x2a, 0x70, 0xc3, 0xcc, 0x4f, 0x84, + 0x33, 0xd8, 0x74, 0x21, 0xd4, 0xa2, 0x5d, 0xdc, 0x09, 0x84, 0xda, 0xa9, 0x16, 0xc2, 0x02, 0x83, + 0x62, 0x51, 0xca, 0x32, 0xb4, 0xb0, 0x0d, 0x98, 0xc3, 0x45, 0x96, 0x97, 0x34, 0x43, 0x8b, 0x56, + 0x86, 0x0d, 0x4c, 0xca, 0x41, 0x98, 0x65, 0xc1, 0x5c, 0x6a, 0x19, 0x5b, 0x6a, 0x1b, 0x26, 0x42, + 0xd3, 0x9c, 0xc4, 0x75, 0xb0, 0xf7, 0xf4, 0x39, 0xf5, 0x8c, 0xba, 0x3c, 0xe0, 0x26, 0x63, 0x7d, + 0xca, 0xd0, 0xa7, 0x7a, 0xb7, 0x7e, 0xfd, 0x66, 0xcc, 0x0c, 0xb0, 0xee, 0x79, 0x43, 0x66, 0x1d, + 0x4e, 0xb7, 0xc3, 0xda, 0x7a, 0xe4, 0x87, 0x91, 0x9f, 0xec, 0xce, 0x37, 0xbd, 0x38, 0x66, 0x13, + 0x63, 0xdc, 0xd4, 0xc7, 0xd6, 0x73, 0x70, 0x70, 0x6e, 0x4d, 0x7a, 0x20, 0x6b, 0x0b, 0x20, 0x0b, + 0x73, 0x2c, 0xf2, 0x9d, 0x4c, 0x22, 0x62, 0x55, 0xea, 0x9e, 0x82, 0x93, 0x95, 0x4e, 0xbb, 0xdd, + 0xf4, 0x49, 0x4d, 0x79, 0xc7, 0xdc, 0x0f, 0xc2, 0x09, 0x91, 0x59, 0x59, 0x69, 0x3f, 0x87, 0x7a, + 0x07, 0xc0, 0xfd, 0x79, 0x38, 0x91, 0xd9, 0x4a, 0x6f, 0x13, 0xb9, 0xe3, 0xfe, 0x97, 0x01, 0x5e, + 0x45, 0x0b, 0x22, 0x43, 0xaf, 0x64, 0xb5, 0x1c, 0x3b, 0x39, 0x82, 0x35, 0xfd, 0x46, 0x24, 0xfc, + 0xcd, 0xd3, 0x98, 0x1a, 0xf2, 0x0e, 0x89, 0xb5, 0xab, 0x5e, 0xec, 0xa6, 0x05, 0xdf, 0x87, 0x8c, + 0x8b, 0x28, 0xaf, 0x03, 0x28, 0xb6, 0x32, 0x0d, 0x85, 0xed, 0x7e, 0xb2, 0x15, 0xaf, 0x20, 0x31, + 0xd6, 0x38, 0xa2, 0x00, 0x86, 0x59, 0x43, 0x88, 0xbc, 0x88, 0x6c, 0xad, 0xaf, 0x4c, 0xc9, 0x5c, + 0xe5, 0xb4, 0xb1, 0x64, 0xe2, 0x7e, 0xb6, 0x00, 0xf9, 0xb1, 0x8e, 0xe8, 0xf5, 0xee, 0x0f, 0xfe, + 0x8c, 0xc5, 0x81, 0x10, 0xc1, 0x96, 0xbd, 0xbf, 0x79, 0x60, 0x7e, 0xf3, 0x55, 0x4b, 0xe3, 0x20, + 0xf8, 0x76, 0x7d, 0x79, 0xf7, 0x7f, 0x3a, 0x50, 0xda, 0xd8, 0x58, 0x51, 0xca, 0x00, 0x86, 0xb3, + 0x31, 0x77, 0x4a, 0xb2, 0x80, 0x8e, 0xf9, 0xb0, 0xd5, 0xe6, 0xf1, 0x1d, 0x22, 0xee, 0x84, 0xa5, + 0x01, 0xaf, 0xe4, 0x62, 0xe0, 0x1e, 0x35, 0xd1, 0x15, 0x38, 0xa5, 0x97, 0x54, 0xb4, 0x47, 0x59, + 0x8b, 0x22, 0xe5, 0x57, 0x77, 0x31, 0xce, 0xab, 0x93, 0x25, 0x25, 0xec, 0xdf, 0xc2, 0x03, 0xdb, + 0x45, 0x4a, 0x14, 0xe3, 0xbc, 0x3a, 0xee, 0x1a, 0x94, 0x36, 0xbc, 0x48, 0x75, 0xfc, 0x43, 0x30, + 0x59, 0x0d, 0x5b, 0x52, 0xc1, 0x59, 0x21, 0x3b, 0xa4, 0x29, 0xba, 0xcc, 0x9f, 0x3a, 0xca, 0x94, + 0xe1, 0x2e, 0x6c, 0xf7, 0x37, 0x1f, 0x04, 0x75, 0x67, 0xb9, 0x8f, 0x3d, 0xb8, 0xad, 0xa2, 0xc0, + 0x8b, 0x96, 0xa3, 0xc0, 0xd5, 0x6e, 0x94, 0x89, 0x04, 0x4f, 0xd2, 0x48, 0xf0, 0x21, 0xdb, 0x91, + 0xe0, 0x4a, 0x2d, 0xef, 0x8a, 0x06, 0xff, 0xb2, 0x03, 0x63, 0x41, 0x58, 0x23, 0xca, 0x61, 0x3b, + 0xcc, 0x56, 0xf8, 0x0b, 0xf6, 0x2e, 0xd5, 0xf0, 0xa8, 0x66, 0x41, 0x9e, 0xdf, 0x50, 0x50, 0x9b, + 0xb8, 0x5e, 0x84, 0x8d, 0x76, 0xa0, 0x45, 0xcd, 0x12, 0xce, 0x1d, 0x4e, 0xf7, 0xe7, 0x9d, 0x28, + 0x6f, 0x6b, 0xd6, 0xbe, 0xa9, 0x69, 0x96, 0xa3, 0xb6, 0x2c, 0xbc, 0xf2, 0x7e, 0xa9, 0xe6, 0x37, + 0x93, 0x99, 0xec, 0x53, 0x8d, 0xd3, 0x85, 0x21, 0x7e, 0x95, 0x41, 0x24, 0x97, 0x63, 0xee, 0x5c, + 0x7e, 0xcd, 0x01, 0x8b, 0x12, 0x94, 0xc8, 0xe0, 0x9e, 0x92, 0xad, 0x77, 0x69, 0x8c, 0xe0, 0xa1, + 0xfc, 0xe8, 0x1e, 0xf4, 0xb4, 0x6e, 0xa9, 0x18, 0xeb, 0xc7, 0x52, 0x31, 0xde, 0xd3, 0x4a, 0xf1, + 0x79, 0x07, 0xc6, 0xaa, 0xda, 0x3b, 0x31, 0xe5, 0x47, 0x6d, 0x3d, 0xd7, 0x9f, 0xf7, 0x9c, 0x0f, + 0xf7, 0x12, 0x1a, 0xef, 0xd2, 0x18, 0xdc, 0x59, 0x46, 0x5d, 0x66, 0x96, 0x61, 0xca, 0x91, 0x95, + 0x4c, 0x35, 0xa6, 0x99, 0x47, 0x06, 0x49, 0x53, 0x18, 0x16, 0xbc, 0xd0, 0xab, 0x30, 0x22, 0x6f, + 0xc3, 0x88, 0x5b, 0x23, 0xd8, 0x86, 0xdb, 0xc6, 0xf4, 0x0d, 0xcb, 0x34, 0x9c, 0x1c, 0x8a, 0x15, + 0x47, 0xd4, 0x80, 0x81, 0x9a, 0x57, 0x17, 0xf7, 0x47, 0x56, 0xed, 0xa4, 0x39, 0x96, 0x3c, 0xd9, + 0x21, 0x76, 0x61, 0x76, 0x09, 0x53, 0x16, 0xe8, 0x66, 0xfa, 0xd0, 0xc6, 0xa4, 0xb5, 0xdd, 0xd7, + 0x54, 0x24, 0xb9, 0x4e, 0xd0, 0xf5, 0x6e, 0x47, 0x4d, 0xb8, 0xd3, 0xff, 0x0a, 0x63, 0xbb, 0x68, + 0x27, 0x4f, 0x32, 0xcf, 0x7c, 0x94, 0xba, 0xe4, 0x29, 0x97, 0x46, 0x92, 0xb4, 0xcb, 0x3f, 0x6b, + 0x8b, 0x0b, 0xcb, 0xdf, 0xc3, 0xb8, 0xd0, 0xff, 0x30, 0xa3, 0x8e, 0x9a, 0xea, 0xd5, 0xff, 0x9f, + 0xb3, 0xb5, 0xb7, 0xf0, 0xf8, 0xa1, 0xbc, 0x37, 0xfe, 0xd1, 0x25, 0x18, 0xe6, 0xef, 0x45, 0xf1, + 0xfb, 0x3b, 0xa5, 0x8b, 0x53, 0xbd, 0x5f, 0x9d, 0x4a, 0x37, 0x0a, 0xfe, 0x3b, 0xc6, 0xb2, 0x2e, + 0xfa, 0x82, 0x03, 0x13, 0x54, 0xa2, 0xa6, 0x0f, 0x5c, 0x95, 0x91, 0x2d, 0x99, 0x75, 0x2d, 0xa6, + 0x1a, 0x89, 0x94, 0x35, 0xea, 0x20, 0x79, 0xc5, 0x60, 0x87, 0x33, 0xec, 0xd1, 0x6b, 0x30, 0x12, + 0xfb, 0x35, 0x52, 0xf5, 0xa2, 0xb8, 0x7c, 0xea, 0x78, 0x9a, 0x92, 0x3a, 0xf0, 0x04, 0x23, 0xac, + 0x58, 0xa2, 0x5f, 0x63, 0x0f, 0x10, 0x57, 0x1b, 0xfe, 0x0e, 0x59, 0x09, 0xab, 0xfc, 0xe0, 0x73, + 0xda, 0xd6, 0xda, 0x97, 0xae, 0x4a, 0x49, 0x59, 0xf8, 0xb5, 0x4c, 0x76, 0x38, 0xcb, 0x1f, 0xfd, + 0x4d, 0x07, 0xce, 0xf0, 0x97, 0x40, 0xb2, 0x8f, 0xdb, 0x9c, 0x39, 0xa2, 0x11, 0x8b, 0x5d, 0x3c, + 0x9a, 0xcd, 0x23, 0x89, 0xf3, 0x39, 0xb1, 0xbc, 0xdd, 0xe6, 0x7b, 0x64, 0x67, 0xad, 0x3a, 0xb2, + 0xfb, 0x7f, 0x83, 0x0c, 0x3d, 0x01, 0xa5, 0xb6, 0xd8, 0x0e, 0xfd, 0xb8, 0xc5, 0xae, 0x91, 0x0d, + 0xf0, 0x0b, 0xbe, 0xeb, 0x29, 0x18, 0xeb, 0x38, 0x46, 0x12, 0xf7, 0xc7, 0x0e, 0x4a, 0xe2, 0x8e, + 0xae, 0x41, 0x29, 0x09, 0x9b, 0x22, 0x8f, 0x71, 0x5c, 0x2e, 0xb3, 0x19, 0x78, 0x3e, 0x6f, 0x6d, + 0x6d, 0x28, 0xb4, 0xf4, 0xac, 0x9f, 0xc2, 0x62, 0xac, 0xd3, 0x61, 0x81, 0xf7, 0xe2, 0x85, 0x95, + 0x88, 0x1d, 0xf2, 0xef, 0xcd, 0x04, 0xde, 0xeb, 0x85, 0xd8, 0xc4, 0x45, 0x4b, 0x70, 0xb2, 0xdd, + 0x65, 0x25, 0xe0, 0xd7, 0x57, 0x55, 0x8c, 0x4c, 0xb7, 0x89, 0xa0, 0xbb, 0x4e, 0x8f, 0x44, 0xe5, + 0xf7, 0x1f, 0x25, 0x51, 0x39, 0xaa, 0xc1, 0xfd, 0x5e, 0x27, 0x09, 0x59, 0xe6, 0x29, 0xb3, 0x0a, + 0xbf, 0x59, 0xf0, 0x20, 0xbf, 0xac, 0xb0, 0xbf, 0x37, 0x7d, 0xff, 0xec, 0x01, 0x78, 0xf8, 0x40, + 0x2a, 0xe8, 0x65, 0x18, 0x21, 0x22, 0xd9, 0x7a, 0xf9, 0x67, 0x6c, 0x6d, 0xfd, 0x66, 0xfa, 0x76, + 0x19, 0xb4, 0xcd, 0x61, 0x58, 0xf1, 0x43, 0x1b, 0x50, 0x6a, 0x84, 0x71, 0x32, 0xdb, 0xf4, 0xbd, + 0x98, 0xc4, 0xe5, 0x07, 0xd8, 0x54, 0xc8, 0xd5, 0xa8, 0x2e, 0x4b, 0xb4, 0x74, 0x26, 0x5c, 0x4e, + 0x6b, 0x62, 0x9d, 0x0c, 0x22, 0xcc, 0x49, 0xcd, 0xae, 0x55, 0x48, 0x07, 0xdc, 0x79, 0xd6, 0xb1, + 0x47, 0xf2, 0x28, 0xaf, 0x87, 0xb5, 0x8a, 0x89, 0xad, 0xbc, 0xd4, 0x3a, 0x10, 0x67, 0x69, 0xa2, + 0xa7, 0x60, 0xac, 0x1d, 0xd6, 0x2a, 0x6d, 0x52, 0x5d, 0xf7, 0x92, 0x6a, 0xa3, 0x3c, 0x6d, 0x5a, + 0x1b, 0xd7, 0xb5, 0x32, 0x6c, 0x60, 0xa2, 0x36, 0x0c, 0xb7, 0x78, 0xa6, 0x91, 0xf2, 0x43, 0xb6, + 0x4e, 0x2c, 0x22, 0x75, 0x89, 0xb0, 0x0c, 0xf0, 0x1f, 0x58, 0xb2, 0x41, 0xff, 0xc0, 0x81, 0x13, + 0x99, 0xeb, 0x8e, 0xe5, 0x77, 0xd9, 0xf4, 0xed, 0x68, 0x84, 0xe7, 0x1e, 0x61, 0xc3, 0x67, 0x02, + 0x6f, 0x75, 0x83, 0x70, 0xb6, 0x45, 0x7c, 0x5c, 0x58, 0xba, 0xa0, 0xf2, 0xc3, 0xf6, 0xc6, 0x85, + 0x11, 0x94, 0xe3, 0xc2, 0x7e, 0x60, 0xc9, 0x06, 0x3d, 0x06, 0xc3, 0x22, 0x05, 0x68, 0xf9, 0x11, + 0xd3, 0xf5, 0x2f, 0x42, 0x99, 0xb1, 0x2c, 0xef, 0x4a, 0x01, 0xf4, 0xb8, 0xad, 0x14, 0x40, 0xea, + 0xbc, 0x77, 0xf8, 0x14, 0x40, 0x53, 0x1f, 0x84, 0x93, 0x5d, 0xa7, 0xc4, 0x43, 0xe5, 0xe0, 0xb9, + 0xc3, 0x1c, 0x3e, 0xee, 0x6f, 0x38, 0xa0, 0x27, 0x7d, 0xb0, 0xfe, 0x6c, 0xd3, 0x53, 0x30, 0x56, + 0xe5, 0xaf, 0xe8, 0xf2, 0xb4, 0x11, 0x83, 0xa6, 0x31, 0x7b, 0x5e, 0x2b, 0xc3, 0x06, 0xa6, 0x7b, + 0x19, 0x50, 0xf7, 0x9b, 0x1a, 0x47, 0xf2, 0x0a, 0xfd, 0x23, 0x07, 0xc6, 0x0d, 0xf5, 0xc6, 0xba, + 0xc7, 0x7a, 0x11, 0x50, 0xcb, 0x8f, 0xa2, 0x30, 0xd2, 0x9f, 0x2b, 0x15, 0xa9, 0x5d, 0x58, 0x24, + 0xcb, 0x6a, 0x57, 0x29, 0xce, 0xa9, 0xe1, 0xfe, 0xd3, 0x41, 0x48, 0xaf, 0x62, 0xa8, 0x8c, 0xe3, + 0x4e, 0xcf, 0x8c, 0xe3, 0x8f, 0xc3, 0xc8, 0x8b, 0x71, 0x18, 0xac, 0xa7, 0x79, 0xc9, 0xd5, 0xb7, + 0x78, 0xba, 0xb2, 0x76, 0x95, 0x61, 0x2a, 0x0c, 0x86, 0xfd, 0xd2, 0xa2, 0xdf, 0x4c, 0xba, 0x13, + 0x57, 0x3f, 0xfd, 0x0c, 0x87, 0x63, 0x85, 0xc1, 0x5e, 0x2e, 0xdd, 0x21, 0xca, 0xcb, 0x91, 0xbe, + 0x5c, 0xca, 0x9f, 0xcb, 0x61, 0x65, 0xe8, 0x02, 0x8c, 0x2a, 0x0f, 0x89, 0x70, 0xbb, 0xa8, 0x91, + 0x52, 0x6e, 0x14, 0x9c, 0xe2, 0x30, 0xdd, 0x55, 0x58, 0xd5, 0x85, 0xb5, 0xa7, 0x62, 0xe3, 0x24, + 0x95, 0xb1, 0xd3, 0xf3, 0x0d, 0x4b, 0x82, 0xb1, 0x62, 0x99, 0xe7, 0xb5, 0x1f, 0x3d, 0x16, 0xaf, + 0xbd, 0x76, 0x2f, 0xa8, 0xd8, 0xef, 0xbd, 0x20, 0x73, 0x6e, 0x8f, 0xf4, 0x35, 0xb7, 0x3f, 0x3d, + 0x00, 0xc3, 0xcf, 0x92, 0x88, 0x3d, 0xf9, 0xf0, 0x18, 0x0c, 0xef, 0xf0, 0x7f, 0xb3, 0x97, 0xca, + 0x05, 0x06, 0x96, 0xe5, 0xf4, 0xbb, 0x6d, 0x76, 0xfc, 0x66, 0x6d, 0x21, 0x5d, 0xc5, 0x69, 0x4a, + 0x56, 0x59, 0x80, 0x53, 0x1c, 0x5a, 0xa1, 0x4e, 0x0f, 0x21, 0xad, 0x96, 0x9f, 0x64, 0x83, 0xf0, + 0x96, 0x64, 0x01, 0x4e, 0x71, 0xd0, 0x23, 0x30, 0x54, 0xf7, 0x93, 0x0d, 0xaf, 0x9e, 0x75, 0xfb, + 0x2e, 0x31, 0x28, 0x16, 0xa5, 0xcc, 0xe7, 0xe7, 0x27, 0x1b, 0x11, 0x61, 0x46, 0xe8, 0xae, 0xac, + 0x38, 0x4b, 0x5a, 0x19, 0x36, 0x30, 0x59, 0x93, 0x42, 0xd1, 0x33, 0x11, 0x81, 0x9c, 0x36, 0x49, + 0x16, 0xe0, 0x14, 0x87, 0xce, 0xff, 0x6a, 0xd8, 0x6a, 0xfb, 0x4d, 0x11, 0x1b, 0xaf, 0xcd, 0xff, + 0x79, 0x01, 0xc7, 0x0a, 0x83, 0x62, 0x53, 0x11, 0x46, 0xc5, 0x4f, 0xf6, 0x95, 0xc8, 0x75, 0x01, + 0xc7, 0x0a, 0xc3, 0x7d, 0x16, 0xc6, 0xf9, 0x4a, 0x9e, 0x6f, 0x7a, 0x7e, 0x6b, 0x69, 0x1e, 0x5d, + 0xea, 0xba, 0x4f, 0xf2, 0x58, 0xce, 0x7d, 0x92, 0x33, 0x46, 0xa5, 0xee, 0x7b, 0x25, 0xee, 0x0f, + 0x0a, 0x30, 0x72, 0x17, 0x1f, 0xda, 0xbd, 0xeb, 0x6f, 0xc6, 0xa3, 0x9b, 0x99, 0x47, 0x76, 0xd7, + 0x6d, 0x5e, 0xf3, 0x3b, 0xf0, 0x81, 0xdd, 0xff, 0x5a, 0x80, 0xb3, 0x12, 0x55, 0x1e, 0x3b, 0x97, + 0xe6, 0xd9, 0xe3, 0x85, 0xc7, 0x3f, 0xd0, 0x91, 0x31, 0xd0, 0xeb, 0xf6, 0x0e, 0xce, 0x4b, 0xf3, + 0x3d, 0x87, 0xfa, 0xe5, 0xcc, 0x50, 0x63, 0xab, 0x5c, 0x0f, 0x1e, 0xec, 0x3f, 0x77, 0x60, 0x2a, + 0x7f, 0xb0, 0xef, 0xc2, 0xbb, 0xc6, 0xaf, 0x99, 0xef, 0x1a, 0xff, 0xa2, 0xbd, 0x29, 0x66, 0x76, + 0xa5, 0xc7, 0x0b, 0xc7, 0xff, 0xc3, 0x81, 0xd3, 0xb2, 0x02, 0xdb, 0x3d, 0xe7, 0xfc, 0x80, 0x45, + 0x26, 0x1d, 0xff, 0x34, 0x7b, 0xd5, 0x98, 0x66, 0xcf, 0xdb, 0xeb, 0xb8, 0xde, 0x8f, 0x5e, 0x13, + 0xce, 0xfd, 0x33, 0x07, 0xca, 0x79, 0x15, 0xee, 0xc2, 0x27, 0x7f, 0xc5, 0xfc, 0xe4, 0xcf, 0x1e, + 0x4f, 0xcf, 0x7b, 0x7f, 0xf0, 0x72, 0xaf, 0x81, 0x42, 0x4d, 0xa9, 0x57, 0x39, 0xb6, 0xdc, 0xe7, + 0x9c, 0x45, 0xbe, 0x82, 0xd6, 0x84, 0xa1, 0x98, 0x85, 0xe0, 0x88, 0x29, 0x70, 0xd9, 0x86, 0xb6, + 0x45, 0xe9, 0x09, 0x77, 0x00, 0xfb, 0x1f, 0x0b, 0x1e, 0xee, 0x6f, 0x15, 0xe0, 0x9c, 0x7a, 0xaf, + 0x9c, 0xec, 0x90, 0x66, 0xba, 0x3e, 0xd8, 0xeb, 0x36, 0x9e, 0xfa, 0x69, 0xef, 0x75, 0x9b, 0x94, + 0x45, 0xba, 0x16, 0x52, 0x18, 0xd6, 0x78, 0xa2, 0x0a, 0x9c, 0x61, 0xaf, 0xd1, 0x2c, 0xfa, 0x81, + 0xd7, 0xf4, 0x5f, 0x26, 0x11, 0x26, 0xad, 0x70, 0xc7, 0x6b, 0x0a, 0x4d, 0x5d, 0xe5, 0x15, 0x58, + 0xcc, 0x43, 0xc2, 0xf9, 0x75, 0xbb, 0xcc, 0x08, 0x03, 0xfd, 0x9a, 0x11, 0xdc, 0x3f, 0x76, 0x60, + 0xec, 0x2e, 0xbe, 0xee, 0x1e, 0x9a, 0x4b, 0xe2, 0x69, 0x7b, 0x4b, 0xa2, 0xc7, 0x32, 0xd8, 0x2b, + 0x42, 0xd7, 0x83, 0xd7, 0xe8, 0x33, 0x8e, 0x0a, 0x52, 0xe2, 0xc1, 0xa0, 0x1f, 0xb1, 0xd7, 0x8e, + 0xc3, 0x64, 0xbf, 0x45, 0x5f, 0xcb, 0xd8, 0x03, 0x0a, 0xb6, 0x12, 0xd5, 0x75, 0xb5, 0xe6, 0x08, + 0xa9, 0x81, 0xbf, 0xec, 0x00, 0xf0, 0x76, 0x8a, 0xa7, 0x07, 0x68, 0xdb, 0x36, 0x8f, 0x6d, 0xa4, + 0x28, 0x13, 0xde, 0x34, 0xb5, 0x84, 0xd2, 0x02, 0xac, 0xb5, 0xe4, 0x0e, 0x72, 0xfe, 0xde, 0x71, + 0xba, 0xe1, 0x2f, 0x38, 0x70, 0x22, 0xd3, 0xdc, 0x9c, 0xfa, 0x5b, 0xe6, 0xfb, 0xac, 0x16, 0x34, + 0x2b, 0x33, 0x21, 0xbd, 0x6e, 0x3c, 0xf9, 0xe7, 0x6e, 0xba, 0x80, 0x99, 0x6c, 0x7f, 0x05, 0x46, + 0xa5, 0xe5, 0x43, 0x4e, 0x6f, 0x9b, 0xef, 0x54, 0xab, 0xe3, 0x8d, 0x84, 0xc4, 0x38, 0xe5, 0x97, + 0x89, 0x81, 0x2c, 0xf4, 0x15, 0x03, 0xf9, 0xce, 0xbe, 0x72, 0x9d, 0x6f, 0x6c, 0x1f, 0x3c, 0x16, + 0x63, 0xfb, 0xfd, 0xd6, 0x8d, 0xed, 0x0f, 0xdc, 0x65, 0x63, 0xbb, 0xe6, 0xcf, 0x2c, 0xde, 0x81, + 0x3f, 0xf3, 0x15, 0x38, 0xbd, 0x93, 0x1e, 0x3a, 0xd5, 0x4c, 0x12, 0xc9, 0xcd, 0x1e, 0xcb, 0x35, + 0xb1, 0xd3, 0x03, 0x74, 0x9c, 0x90, 0x20, 0xd1, 0x8e, 0xab, 0x69, 0xf8, 0xe5, 0xb3, 0x39, 0xe4, + 0x70, 0x2e, 0x93, 0xac, 0x63, 0x6a, 0xb8, 0x0f, 0xc7, 0xd4, 0xb7, 0x1d, 0x38, 0xe3, 0x75, 0x5d, + 0x60, 0xc4, 0x64, 0x4b, 0x44, 0xc7, 0x5c, 0xb7, 0xa7, 0x42, 0x18, 0xe4, 0x85, 0x07, 0x30, 0xaf, + 0x08, 0xe7, 0x37, 0x08, 0x3d, 0x9c, 0x46, 0x09, 0xf0, 0xa0, 0xdd, 0x7c, 0x97, 0xfe, 0xd7, 0xb2, + 0xa1, 0x47, 0xc0, 0x86, 0xfe, 0x63, 0x76, 0x4f, 0xdb, 0x16, 0xc2, 0x8f, 0x4a, 0x77, 0x10, 0x7e, + 0x94, 0xf1, 0x12, 0x8e, 0x59, 0xf2, 0x12, 0x06, 0x30, 0xe9, 0xb7, 0xbc, 0x3a, 0x59, 0xef, 0x34, + 0x9b, 0xfc, 0x46, 0x92, 0x7c, 0x49, 0x3c, 0xd7, 0x82, 0xb7, 0x12, 0x56, 0xbd, 0xa6, 0xc8, 0xdd, + 0xa2, 0x02, 0x96, 0xd5, 0xcd, 0xab, 0x2b, 0x19, 0x4a, 0xb8, 0x8b, 0x36, 0x9d, 0xb0, 0x2c, 0x4f, + 0x27, 0x49, 0xe8, 0x68, 0xb3, 0x18, 0x97, 0x11, 0x3e, 0x61, 0x2f, 0xa7, 0x60, 0xac, 0xe3, 0xa0, + 0x65, 0x18, 0xad, 0x05, 0xb1, 0xb8, 0x8b, 0x7d, 0x82, 0x09, 0xb3, 0x77, 0x53, 0x11, 0xb8, 0x70, + 0xb5, 0xa2, 0x6e, 0x61, 0xdf, 0x9f, 0x93, 0x78, 0x56, 0x95, 0xe3, 0xb4, 0x3e, 0x5a, 0x65, 0xc4, + 0xc4, 0x1b, 0x89, 0x3c, 0xf4, 0xe4, 0xc1, 0x1e, 0x5e, 0xb0, 0x85, 0xab, 0xf2, 0x95, 0xc7, 0x71, + 0xc1, 0x4e, 0x3c, 0x76, 0x98, 0x52, 0xd0, 0x5e, 0x74, 0x3f, 0x79, 0xe0, 0x8b, 0xee, 0x2c, 0xe3, + 0x74, 0xd2, 0x54, 0x9e, 0xec, 0xf3, 0xd6, 0x32, 0x4e, 0xa7, 0x41, 0x9d, 0x22, 0xe3, 0x74, 0x0a, + 0xc0, 0x3a, 0x4b, 0xb4, 0xd6, 0xcb, 0xa3, 0x7f, 0x8a, 0x09, 0x8d, 0xc3, 0xfb, 0xe7, 0xf5, 0xd0, + 0xef, 0xd3, 0x07, 0x85, 0x7e, 0x77, 0xbb, 0xa2, 0xcf, 0x1c, 0xc2, 0x15, 0xdd, 0x60, 0xb9, 0x80, + 0x97, 0xe6, 0x85, 0xf7, 0xdf, 0xc2, 0xf9, 0x8e, 0xe5, 0x9c, 0xe1, 0x41, 0xb2, 0xec, 0x5f, 0xcc, + 0x19, 0xf4, 0x8c, 0x8e, 0x3f, 0x77, 0xe4, 0xe8, 0xf8, 0x8c, 0x3f, 0xf7, 0xde, 0x63, 0xf3, 0xe7, + 0x4e, 0xdd, 0x05, 0x7f, 0xee, 0x7d, 0x7d, 0xfb, 0x73, 0x6f, 0xc2, 0xa9, 0x76, 0x58, 0x5b, 0xf0, + 0xe3, 0xa8, 0xc3, 0xee, 0x5b, 0xce, 0x75, 0x6a, 0x75, 0x92, 0x30, 0x87, 0x70, 0xe9, 0xe2, 0xbb, + 0xf5, 0x46, 0xb6, 0xd9, 0xaa, 0x94, 0x0b, 0x2e, 0x53, 0x81, 0xd9, 0x41, 0x58, 0xb4, 0x6f, 0x4e, + 0x21, 0xce, 0x63, 0xa1, 0x7b, 0x92, 0x1f, 0xbc, 0x3b, 0x9e, 0xe4, 0x0f, 0xc1, 0x48, 0xdc, 0xe8, + 0x24, 0xb5, 0xf0, 0x46, 0xc0, 0xc2, 0x05, 0x46, 0xe7, 0xde, 0xa5, 0xec, 0xd2, 0x02, 0x7e, 0x6b, + 0x6f, 0x7a, 0x52, 0xfe, 0xaf, 0x99, 0xa4, 0x05, 0x04, 0x7d, 0xbd, 0xc7, 0xcd, 0x2a, 0xf7, 0x38, + 0x6f, 0x56, 0x9d, 0x3b, 0xd4, 0xad, 0xaa, 0x3c, 0x77, 0xf9, 0x43, 0x3f, 0x75, 0xee, 0xf2, 0xaf, + 0x3a, 0x30, 0xbe, 0xa3, 0xdb, 0xff, 0x85, 0x4b, 0xdf, 0x42, 0xc0, 0x90, 0xe1, 0x56, 0x98, 0x73, + 0xa9, 0xd0, 0x32, 0x40, 0xb7, 0xb2, 0x00, 0x6c, 0xb6, 0x24, 0x27, 0x98, 0xe9, 0xe1, 0x77, 0x2a, + 0x98, 0xe9, 0x35, 0x28, 0xb5, 0xc3, 0x9a, 0x3c, 0xb1, 0x32, 0x3f, 0xbf, 0xdd, 0x58, 0x66, 0xae, + 0x7f, 0xa6, 0x2c, 0xb0, 0xce, 0x0f, 0x7d, 0xde, 0x81, 0x49, 0x79, 0xc8, 0x12, 0xfe, 0xbb, 0x58, + 0x44, 0x63, 0xda, 0x3c, 0xdb, 0xf1, 0xe4, 0xd4, 0x19, 0x3e, 0xb8, 0x8b, 0x33, 0x55, 0x48, 0x54, + 0xf0, 0x5b, 0x3d, 0x66, 0x41, 0xc7, 0x42, 0x21, 0x99, 0x4d, 0xc1, 0x58, 0xc7, 0x41, 0xdf, 0x70, + 0xa0, 0xd8, 0x08, 0xc3, 0xed, 0xb8, 0xfc, 0x18, 0x13, 0xe8, 0xcf, 0x59, 0x56, 0x34, 0x2f, 0x53, + 0xda, 0x5c, 0xc3, 0x7c, 0x42, 0x1a, 0x82, 0x18, 0xec, 0xd6, 0xde, 0xf4, 0x84, 0xf1, 0xae, 0x5a, + 0xfc, 0xc6, 0xdb, 0x1a, 0x44, 0x18, 0x2a, 0x59, 0xd3, 0xd0, 0x5b, 0x0e, 0x4c, 0xde, 0xc8, 0x58, + 0x27, 0x44, 0x38, 0x2a, 0xb6, 0x6f, 0xf7, 0xe0, 0xc3, 0x9d, 0x85, 0xe2, 0xae, 0x16, 0xa0, 0xcf, + 0x99, 0x56, 0x4b, 0x1e, 0xb7, 0x6a, 0x71, 0x00, 0x33, 0x56, 0x52, 0x7e, 0x1d, 0x29, 0xdf, 0x7c, + 0x79, 0xe7, 0xc1, 0x22, 0xb4, 0x33, 0xe9, 0xc7, 0xca, 0xa9, 0x4a, 0x4c, 0xe3, 0x89, 0x85, 0xc5, + 0x6e, 0x7c, 0x7e, 0xdd, 0x76, 0xf2, 0xd6, 0x59, 0x98, 0x30, 0x1d, 0x75, 0xe8, 0x3d, 0xe6, 0xdb, + 0x36, 0xe7, 0xb3, 0xcf, 0x84, 0x8c, 0x4b, 0x7c, 0xe3, 0xa9, 0x10, 0xe3, 0x2d, 0x8f, 0xc2, 0xb1, + 0xbe, 0xe5, 0x31, 0x70, 0x77, 0xde, 0xf2, 0x98, 0x3c, 0x8e, 0xb7, 0x3c, 0x4e, 0x1e, 0xea, 0x2d, + 0x0f, 0xed, 0x2d, 0x95, 0xc1, 0xdb, 0xbc, 0xa5, 0x32, 0x0b, 0x27, 0xe4, 0x9d, 0x23, 0x22, 0x9e, + 0x4b, 0xe0, 0x3e, 0x7c, 0xf5, 0xdc, 0xff, 0xbc, 0x59, 0x8c, 0xb3, 0xf8, 0x74, 0x91, 0x15, 0x03, + 0x56, 0x73, 0xc8, 0x56, 0x50, 0x96, 0x39, 0xb5, 0xd8, 0x59, 0x58, 0x88, 0x28, 0x19, 0x65, 0x5d, + 0x64, 0xb0, 0x5b, 0xf2, 0x1f, 0xcc, 0x5b, 0x80, 0x5e, 0x80, 0x72, 0xb8, 0xb5, 0xd5, 0x0c, 0xbd, + 0x5a, 0xfa, 0xe0, 0x88, 0x0c, 0x32, 0xe0, 0xb7, 0x6a, 0x55, 0x46, 0xcd, 0xb5, 0x1e, 0x78, 0xb8, + 0x27, 0x05, 0xf4, 0x6d, 0xaa, 0x98, 0x24, 0x61, 0x44, 0x6a, 0xa9, 0xe1, 0x65, 0x94, 0xf5, 0x99, + 0x58, 0xef, 0x73, 0xc5, 0xe4, 0xc3, 0x7b, 0xaf, 0x3e, 0x4a, 0xa6, 0x14, 0x67, 0x9b, 0x85, 0x22, + 0x38, 0xdb, 0xce, 0xb3, 0xfb, 0xc4, 0xe2, 0xa6, 0xd4, 0x41, 0xd6, 0x27, 0xf5, 0xa8, 0x7d, 0xae, + 0xe5, 0x28, 0xc6, 0x3d, 0x28, 0xeb, 0x8f, 0x82, 0x8c, 0xdc, 0x9d, 0x47, 0x41, 0x3e, 0x0e, 0x50, + 0x95, 0x49, 0xe9, 0xa4, 0x25, 0x61, 0xd9, 0xca, 0x15, 0x1e, 0x4e, 0x53, 0x7b, 0xdf, 0x59, 0xb1, + 0xc1, 0x1a, 0x4b, 0xf4, 0x7f, 0x72, 0x5f, 0xcd, 0xe1, 0xe6, 0x92, 0xba, 0xf5, 0x39, 0xf1, 0x53, + 0xf7, 0x72, 0xce, 0x3f, 0x74, 0x60, 0x8a, 0xcf, 0xbc, 0xac, 0x72, 0x4f, 0x55, 0x0b, 0x71, 0xa7, + 0xc8, 0x76, 0x1c, 0x0a, 0x4f, 0x2e, 0x65, 0x70, 0x65, 0x5e, 0xeb, 0x03, 0x5a, 0x82, 0xbe, 0x9c, + 0x73, 0xa4, 0x38, 0x61, 0xcb, 0x00, 0x99, 0xff, 0xf6, 0xc9, 0xa9, 0xfd, 0x7e, 0x4e, 0x11, 0xff, + 0xa4, 0xa7, 0x7d, 0x14, 0xb1, 0xe6, 0xfd, 0xd2, 0x31, 0xd9, 0x47, 0xf5, 0x07, 0x5a, 0x0e, 0x65, + 0x25, 0xfd, 0x82, 0x03, 0x93, 0x5e, 0x26, 0x6e, 0x84, 0x19, 0x75, 0xac, 0x18, 0x98, 0x66, 0xa3, + 0x34, 0x18, 0x85, 0x29, 0x79, 0xd9, 0x10, 0x15, 0xdc, 0xc5, 0x1c, 0xfd, 0xc0, 0x81, 0xfb, 0xd2, + 0x57, 0x60, 0xe2, 0xf4, 0x8e, 0xb0, 0x68, 0xdc, 0x69, 0xb6, 0x1a, 0x5f, 0xb2, 0xbe, 0x1a, 0x37, + 0x7a, 0xf3, 0xe4, 0xeb, 0xf2, 0x21, 0xb1, 0x2e, 0xef, 0x3b, 0x00, 0x13, 0x1f, 0xd4, 0xf4, 0xa9, + 0xcf, 0x38, 0xfc, 0x99, 0xbc, 0x9e, 0x2a, 0xdf, 0xa6, 0xa9, 0xf2, 0xad, 0xd8, 0x7c, 0xa8, 0x4b, + 0xd7, 0x3d, 0x7f, 0xd5, 0x81, 0xd3, 0x79, 0x3b, 0x52, 0x4e, 0x93, 0x3e, 0x66, 0x36, 0xc9, 0xe2, + 0x29, 0x4b, 0x6f, 0x90, 0x95, 0x57, 0x7e, 0xa6, 0xae, 0xc2, 0x83, 0xb7, 0xfb, 0x8a, 0xb7, 0xa3, + 0x37, 0xa2, 0xab, 0xc5, 0x7f, 0x36, 0xaa, 0xb9, 0x14, 0x13, 0xd2, 0xb6, 0x1e, 0x90, 0x1d, 0xc0, + 0x90, 0x1f, 0x34, 0xfd, 0x80, 0x88, 0x7b, 0xa2, 0x36, 0xcf, 0xb0, 0xe2, 0x9d, 0x2f, 0x4a, 0x1d, + 0x0b, 0x2e, 0xef, 0xb0, 0x87, 0x31, 0xfb, 0x72, 0xe2, 0xe0, 0xdd, 0x7f, 0x39, 0xf1, 0x06, 0x8c, + 0xde, 0xf0, 0x93, 0x06, 0x8b, 0x8c, 0x10, 0x8e, 0x3b, 0x0b, 0xf7, 0x2b, 0x29, 0xb9, 0xb4, 0xef, + 0xd7, 0x25, 0x03, 0x9c, 0xf2, 0x42, 0x17, 0x38, 0x63, 0x16, 0x86, 0x9d, 0x8d, 0x8f, 0xbd, 0x2e, + 0x0b, 0x70, 0x8a, 0x43, 0x07, 0x6b, 0x8c, 0xfe, 0x92, 0xd9, 0xaa, 0x44, 0x02, 0x69, 0x1b, 0x89, + 0x41, 0x05, 0x45, 0x7e, 0x8b, 0xf9, 0xba, 0xc6, 0x03, 0x1b, 0x1c, 0x55, 0x0e, 0xef, 0x91, 0x9e, + 0x39, 0xbc, 0x5f, 0x65, 0x0a, 0x5b, 0xe2, 0x07, 0x1d, 0xb2, 0x16, 0x88, 0xe0, 0xed, 0x15, 0x3b, + 0x77, 0xae, 0x39, 0x4d, 0x7e, 0x04, 0x4f, 0x7f, 0x63, 0x8d, 0x9f, 0xe6, 0x3f, 0x29, 0x1d, 0xe8, + 0x3f, 0x49, 0x4d, 0x2e, 0x63, 0xd6, 0x4d, 0x2e, 0x09, 0x69, 0x5b, 0x31, 0xb9, 0xfc, 0x54, 0x99, + 0x03, 0xfe, 0xdc, 0x01, 0xa4, 0xf4, 0x2e, 0x25, 0x50, 0xef, 0x42, 0x84, 0xe4, 0x27, 0x1c, 0x80, + 0x40, 0xbd, 0xaf, 0x6b, 0x77, 0x17, 0xe4, 0x34, 0xd3, 0x06, 0xa4, 0x30, 0xac, 0xf1, 0x74, 0xff, + 0xd4, 0x49, 0x03, 0x91, 0xd3, 0xbe, 0xdf, 0x85, 0x88, 0xb0, 0x5d, 0x33, 0x22, 0x6c, 0xc3, 0xa2, + 0xe9, 0x5e, 0x75, 0xa3, 0x47, 0x6c, 0xd8, 0x8f, 0x0b, 0x70, 0x42, 0x47, 0xae, 0x90, 0xbb, 0xf1, + 0xb1, 0x6f, 0x18, 0xe1, 0xb0, 0xd7, 0xec, 0xf6, 0xb7, 0x22, 0x3c, 0x40, 0x79, 0xa1, 0xd7, 0x1f, + 0xcf, 0x84, 0x5e, 0x5f, 0xb7, 0xcf, 0xfa, 0xe0, 0xf8, 0xeb, 0xff, 0xe6, 0xc0, 0xa9, 0x4c, 0x8d, + 0xbb, 0x30, 0xc1, 0x76, 0xcc, 0x09, 0xf6, 0x8c, 0xf5, 0x5e, 0xf7, 0x98, 0x5d, 0xdf, 0x2c, 0x74, + 0xf5, 0x96, 0x1d, 0xe2, 0x3e, 0xed, 0x40, 0x91, 0x6a, 0xcb, 0x32, 0x38, 0xeb, 0x63, 0xc7, 0x32, + 0x03, 0x98, 0x5e, 0x2f, 0xa4, 0xb3, 0x6a, 0x1f, 0x83, 0x61, 0xce, 0x7d, 0xea, 0x53, 0x0e, 0x40, + 0x8a, 0xf4, 0x4e, 0xa9, 0xc0, 0xee, 0x77, 0x0a, 0x70, 0x26, 0x77, 0x1a, 0xa1, 0xcf, 0x2a, 0x8b, + 0x9c, 0x63, 0x3b, 0xf4, 0xd0, 0x60, 0xa4, 0x1b, 0xe6, 0xc6, 0x0d, 0xc3, 0x9c, 0xb0, 0xc7, 0xbd, + 0x53, 0x07, 0x18, 0x21, 0xa6, 0xb5, 0xc1, 0xfa, 0x91, 0x93, 0x46, 0xb3, 0xaa, 0x7c, 0x4a, 0x7f, + 0x01, 0x6f, 0xe4, 0xb8, 0x3f, 0xd6, 0xae, 0x2b, 0xc8, 0x8e, 0xde, 0x05, 0x59, 0x71, 0xc3, 0x94, + 0x15, 0xd8, 0xbe, 0x1f, 0xb9, 0x87, 0xb0, 0x78, 0x09, 0xf2, 0x1c, 0xcb, 0xfd, 0xa5, 0xab, 0x34, + 0xee, 0xb6, 0x16, 0xfa, 0xbe, 0xdb, 0x3a, 0x0e, 0xa5, 0xe7, 0x7d, 0x95, 0xea, 0x74, 0x6e, 0xe6, + 0xbb, 0x3f, 0x3c, 0x7f, 0xcf, 0xf7, 0x7e, 0x78, 0xfe, 0x9e, 0x1f, 0xfc, 0xf0, 0xfc, 0x3d, 0x9f, + 0xd8, 0x3f, 0xef, 0x7c, 0x77, 0xff, 0xbc, 0xf3, 0xbd, 0xfd, 0xf3, 0xce, 0x0f, 0xf6, 0xcf, 0x3b, + 0xff, 0x71, 0xff, 0xbc, 0xf3, 0xb7, 0xff, 0xe4, 0xfc, 0x3d, 0xcf, 0x8f, 0xc8, 0x8e, 0xfd, 0xff, + 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0xaa, 0x92, 0x81, 0x73, 0xdd, 0x00, 0x00, } func (m *Amount) Marshal() (dAtA []byte, err error) { @@ -5693,6 +5758,18 @@ func (m *ArtifactLocation) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Plugin != nil { + { + size, err := m.Plugin.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x5a + } if m.Azure != nil { { size, err := m.Azure.MarshalToSizedBuffer(dAtA[:i]) @@ -5931,6 +6008,18 @@ func (m *ArtifactRepository) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.Plugin != nil { + { + size, err := m.Plugin.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } if m.Azure != nil { { size, err := m.Azure.MarshalToSizedBuffer(dAtA[:i]) @@ -10302,6 +10391,85 @@ func (m *Plugin) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } +func (m *PluginArtifact) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PluginArtifact) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PluginArtifact) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Key) + copy(dAtA[i:], m.Key) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Key))) + i-- + dAtA[i] = 0x22 + i = encodeVarintGenerated(dAtA, i, uint64(m.ConnectionTimeoutSeconds)) + i-- + dAtA[i] = 0x18 + i -= len(m.Configuration) + copy(dAtA[i:], m.Configuration) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Configuration))) + i-- + dAtA[i] = 0x12 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *PluginArtifactRepository) Marshal() (dAtA []byte, err error) { + size := m.Size() + dAtA = make([]byte, size) + n, err := m.MarshalToSizedBuffer(dAtA[:size]) + if err != nil { + return nil, err + } + return dAtA[:n], nil +} + +func (m *PluginArtifactRepository) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *PluginArtifactRepository) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + i -= len(m.Configuration) + copy(dAtA[i:], m.Configuration) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Configuration))) + i-- + dAtA[i] = 0x1a + i -= len(m.KeyFormat) + copy(dAtA[i:], m.KeyFormat) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.KeyFormat))) + i-- + dAtA[i] = 0x12 + i -= len(m.Name) + copy(dAtA[i:], m.Name) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Name))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *PodGC) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -14530,6 +14698,10 @@ func (m *ArtifactLocation) Size() (n int) { l = m.Azure.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.Plugin != nil { + l = m.Plugin.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -14599,6 +14771,10 @@ func (m *ArtifactRepository) Size() (n int) { l = m.Azure.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.Plugin != nil { + l = m.Plugin.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -16176,24 +16352,23 @@ func (m *Plugin) Size() (n int) { return n } -func (m *PodGC) Size() (n int) { +func (m *PluginArtifact) Size() (n int) { if m == nil { return 0 } var l int _ = l - l = len(m.Strategy) + l = len(m.Name) n += 1 + l + sovGenerated(uint64(l)) - if m.LabelSelector != nil { - l = m.LabelSelector.Size() - n += 1 + l + sovGenerated(uint64(l)) - } - l = len(m.DeleteDelayDuration) + l = len(m.Configuration) + n += 1 + l + sovGenerated(uint64(l)) + n += 1 + sovGenerated(uint64(m.ConnectionTimeoutSeconds)) + l = len(m.Key) n += 1 + l + sovGenerated(uint64(l)) return n } -func (m *Prometheus) Size() (n int) { +func (m *PluginArtifactRepository) Size() (n int) { if m == nil { return 0 } @@ -16201,11 +16376,43 @@ func (m *Prometheus) Size() (n int) { _ = l l = len(m.Name) n += 1 + l + sovGenerated(uint64(l)) - if len(m.Labels) > 0 { - for _, e := range m.Labels { - l = e.Size() - n += 1 + l + sovGenerated(uint64(l)) - } + l = len(m.KeyFormat) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Configuration) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *PodGC) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Strategy) + n += 1 + l + sovGenerated(uint64(l)) + if m.LabelSelector != nil { + l = m.LabelSelector.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + l = len(m.DeleteDelayDuration) + n += 1 + l + sovGenerated(uint64(l)) + return n +} + +func (m *Prometheus) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Labels) > 0 { + for _, e := range m.Labels { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } } l = len(m.Help) n += 1 + l + sovGenerated(uint64(l)) @@ -17731,6 +17938,7 @@ func (this *ArtifactLocation) String() string { `OSS:` + strings.Replace(this.OSS.String(), "OSSArtifact", "OSSArtifact", 1) + `,`, `GCS:` + strings.Replace(this.GCS.String(), "GCSArtifact", "GCSArtifact", 1) + `,`, `Azure:` + strings.Replace(this.Azure.String(), "AzureArtifact", "AzureArtifact", 1) + `,`, + `Plugin:` + strings.Replace(this.Plugin.String(), "PluginArtifact", "PluginArtifact", 1) + `,`, `}`, }, "") return s @@ -17778,6 +17986,7 @@ func (this *ArtifactRepository) String() string { `OSS:` + strings.Replace(this.OSS.String(), "OSSArtifactRepository", "OSSArtifactRepository", 1) + `,`, `GCS:` + strings.Replace(this.GCS.String(), "GCSArtifactRepository", "GCSArtifactRepository", 1) + `,`, `Azure:` + strings.Replace(this.Azure.String(), "AzureArtifactRepository", "AzureArtifactRepository", 1) + `,`, + `Plugin:` + strings.Replace(this.Plugin.String(), "PluginArtifactRepository", "PluginArtifactRepository", 1) + `,`, `}`, }, "") return s @@ -18957,6 +19166,31 @@ func (this *Plugin) String() string { }, "") return s } +func (this *PluginArtifact) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PluginArtifact{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Configuration:` + fmt.Sprintf("%v", this.Configuration) + `,`, + `ConnectionTimeoutSeconds:` + fmt.Sprintf("%v", this.ConnectionTimeoutSeconds) + `,`, + `Key:` + fmt.Sprintf("%v", this.Key) + `,`, + `}`, + }, "") + return s +} +func (this *PluginArtifactRepository) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&PluginArtifactRepository{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `KeyFormat:` + fmt.Sprintf("%v", this.KeyFormat) + `,`, + `Configuration:` + fmt.Sprintf("%v", this.Configuration) + `,`, + `}`, + }, "") + return s +} func (this *PodGC) String() string { if this == nil { return "nil" @@ -21958,6 +22192,42 @@ func (m *ArtifactLocation) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 11: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Plugin", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Plugin == nil { + m.Plugin = &PluginArtifact{} + } + if err := m.Plugin.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -22543,6 +22813,42 @@ func (m *ArtifactRepository) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Plugin", wireType) + } + var msglen int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + msglen |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + if msglen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + msglen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + if m.Plugin == nil { + m.Plugin = &PluginArtifactRepository{} + } + if err := m.Plugin.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -35910,6 +36216,317 @@ func (m *Plugin) Unmarshal(dAtA []byte) error { } return nil } +func (m *PluginArtifact) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PluginArtifact: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PluginArtifact: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = ArtifactPluginName(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Configuration", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Configuration = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field ConnectionTimeoutSeconds", wireType) + } + m.ConnectionTimeoutSeconds = 0 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + m.ConnectionTimeoutSeconds |= int32(b&0x7F) << shift + if b < 0x80 { + break + } + } + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Key", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Key = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} +func (m *PluginArtifactRepository) Unmarshal(dAtA []byte) error { + l := len(dAtA) + iNdEx := 0 + for iNdEx < l { + preIndex := iNdEx + var wire uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + wire |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + fieldNum := int32(wire >> 3) + wireType := int(wire & 0x7) + if wireType == 4 { + return fmt.Errorf("proto: PluginArtifactRepository: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: PluginArtifactRepository: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Name = ArtifactPluginName(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field KeyFormat", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.KeyFormat = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Configuration", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + stringLen |= uint64(b&0x7F) << shift + if b < 0x80 { + break + } + } + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Configuration = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex + default: + iNdEx = preIndex + skippy, err := skipGenerated(dAtA[iNdEx:]) + if err != nil { + return err + } + if (skippy < 0) || (iNdEx+skippy) < 0 { + return ErrInvalidLengthGenerated + } + if (iNdEx + skippy) > l { + return io.ErrUnexpectedEOF + } + iNdEx += skippy + } + } + + if iNdEx > l { + return io.ErrUnexpectedEOF + } + return nil +} func (m *PodGC) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 diff --git a/pkg/apis/workflow/v1alpha1/generated.proto b/pkg/apis/workflow/v1alpha1/generated.proto index b1377b6e9274..87cee914eb85 100644 --- a/pkg/apis/workflow/v1alpha1/generated.proto +++ b/pkg/apis/workflow/v1alpha1/generated.proto @@ -159,6 +159,9 @@ message ArtifactLocation { // Azure contains Azure Storage artifact location details optional AzureArtifact azure = 10; + + // Plugin contains plugin artifact location details + optional PluginArtifact plugin = 11; } // ArtifactNodeSpec specifies the Artifacts that need to be deleted for a given Node @@ -198,6 +201,9 @@ message ArtifactRepository { // Azure stores artifact in an Azure Storage account optional AzureArtifactRepository azure = 7; + + // Plugin stores artifact in a plugin-specific artifact repository + optional PluginArtifactRepository plugin = 8; } // +protobuf.options.(gogoproto.goproto_stringer)=false @@ -1293,6 +1299,30 @@ message Plugin { optional Object object = 1; } +// PluginArtifact is the location of a plugin artifact +message PluginArtifact { + // Name is the name of the artifact driver plugin + optional string name = 1; + + // Configuration is the plugin defined configuration for the artifact driver plugin + optional string configuration = 2; + + // ConnectionTimeoutSeconds is the timeout for the artifact driver connection, 5 seconds if not set + optional int32 connectionTimeoutSeconds = 3; + + // Key is the path in the artifact repository where the artifact resides + optional string key = 4; +} + +// PluginArtifactRepository defines the controller configuration for a plugin artifact repository +message PluginArtifactRepository { + optional string name = 1; + + optional string keyFormat = 2; + + optional string configuration = 3; +} + // PodGC describes how to delete completed pods as they complete message PodGC { // Strategy is the strategy to use. One of "OnPodCompletion", "OnPodSuccess", "OnWorkflowCompletion", "OnWorkflowSuccess". If unset, does not delete Pods diff --git a/pkg/apis/workflow/v1alpha1/openapi_generated.go b/pkg/apis/workflow/v1alpha1/openapi_generated.go index 09f223f3099b..47584f817cdc 100644 --- a/pkg/apis/workflow/v1alpha1/openapi_generated.go +++ b/pkg/apis/workflow/v1alpha1/openapi_generated.go @@ -111,6 +111,8 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ParallelSteps": schema_pkg_apis_workflow_v1alpha1_ParallelSteps(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Parameter": schema_pkg_apis_workflow_v1alpha1_Parameter(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Plugin": schema_pkg_apis_workflow_v1alpha1_Plugin(ref), + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.PluginArtifact": schema_pkg_apis_workflow_v1alpha1_PluginArtifact(ref), + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.PluginArtifactRepository": schema_pkg_apis_workflow_v1alpha1_PluginArtifactRepository(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.PodGC": schema_pkg_apis_workflow_v1alpha1_PodGC(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.Prometheus": schema_pkg_apis_workflow_v1alpha1_Prometheus(ref), "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.RawArtifact": schema_pkg_apis_workflow_v1alpha1_RawArtifact(ref), @@ -415,6 +417,12 @@ func schema_pkg_apis_workflow_v1alpha1_Artifact(ref common.ReferenceCallback) co Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.AzureArtifact"), }, }, + "plugin": { + SchemaProps: spec.SchemaProps{ + Description: "Plugin contains plugin artifact location details", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.PluginArtifact"), + }, + }, "globalName": { SchemaProps: spec.SchemaProps{ Description: "GlobalName exports an output artifact to the global scope, making it available as '{{workflow.outputs.artifacts.XXXX}} and in workflow.status.outputs.artifacts", @@ -474,7 +482,7 @@ func schema_pkg_apis_workflow_v1alpha1_Artifact(ref common.ReferenceCallback) co }, }, Dependencies: []string{ - "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArchiveStrategy", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactGC", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactoryArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.AzureArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GCSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GitArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HDFSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HTTPArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.OSSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.RawArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.S3Artifact"}, + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArchiveStrategy", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactGC", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactoryArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.AzureArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GCSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GitArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HDFSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HTTPArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.OSSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.PluginArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.RawArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.S3Artifact"}, } } @@ -641,11 +649,17 @@ func schema_pkg_apis_workflow_v1alpha1_ArtifactLocation(ref common.ReferenceCall Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.AzureArtifact"), }, }, + "plugin": { + SchemaProps: spec.SchemaProps{ + Description: "Plugin contains plugin artifact location details", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.PluginArtifact"), + }, + }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactoryArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.AzureArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GCSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GitArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HDFSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HTTPArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.OSSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.RawArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.S3Artifact"}, + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactoryArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.AzureArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GCSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GitArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HDFSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HTTPArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.OSSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.PluginArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.RawArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.S3Artifact"}, } } @@ -782,6 +796,12 @@ func schema_pkg_apis_workflow_v1alpha1_ArtifactPaths(ref common.ReferenceCallbac Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.AzureArtifact"), }, }, + "plugin": { + SchemaProps: spec.SchemaProps{ + Description: "Plugin contains plugin artifact location details", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.PluginArtifact"), + }, + }, "globalName": { SchemaProps: spec.SchemaProps{ Description: "GlobalName exports an output artifact to the global scope, making it available as '{{workflow.outputs.artifacts.XXXX}} and in workflow.status.outputs.artifacts", @@ -841,7 +861,7 @@ func schema_pkg_apis_workflow_v1alpha1_ArtifactPaths(ref common.ReferenceCallbac }, }, Dependencies: []string{ - "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArchiveStrategy", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactGC", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactoryArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.AzureArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GCSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GitArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HDFSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HTTPArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.OSSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.RawArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.S3Artifact"}, + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArchiveStrategy", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactGC", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactoryArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.AzureArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GCSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GitArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HDFSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HTTPArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.OSSArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.PluginArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.RawArtifact", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.S3Artifact"}, } } @@ -895,11 +915,17 @@ func schema_pkg_apis_workflow_v1alpha1_ArtifactRepository(ref common.ReferenceCa Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.AzureArtifactRepository"), }, }, + "plugin": { + SchemaProps: spec.SchemaProps{ + Description: "Plugin stores artifact in a plugin-specific artifact repository", + Ref: ref("github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.PluginArtifactRepository"), + }, + }, }, }, }, Dependencies: []string{ - "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactoryArtifactRepository", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.AzureArtifactRepository", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GCSArtifactRepository", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HDFSArtifactRepository", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.OSSArtifactRepository", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.S3ArtifactRepository"}, + "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.ArtifactoryArtifactRepository", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.AzureArtifactRepository", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.GCSArtifactRepository", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.HDFSArtifactRepository", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.OSSArtifactRepository", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.PluginArtifactRepository", "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1.S3ArtifactRepository"}, } } @@ -4925,6 +4951,85 @@ func schema_pkg_apis_workflow_v1alpha1_Plugin(ref common.ReferenceCallback) comm } } +func schema_pkg_apis_workflow_v1alpha1_PluginArtifact(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PluginArtifact is the location of a plugin artifact", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Description: "Name is the name of the artifact driver plugin", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "configuration": { + SchemaProps: spec.SchemaProps{ + Description: "Configuration is the plugin defined configuration for the artifact driver plugin", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "connectionTimeoutSeconds": { + SchemaProps: spec.SchemaProps{ + Description: "ConnectionTimeoutSeconds is the timeout for the artifact driver connection, 5 seconds if not set", + Type: []string{"integer"}, + Format: "int32", + }, + }, + "key": { + SchemaProps: spec.SchemaProps{ + Description: "Key is the path in the artifact repository where the artifact resides", + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name", "configuration", "key"}, + }, + }, + } +} + +func schema_pkg_apis_workflow_v1alpha1_PluginArtifactRepository(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "PluginArtifactRepository defines the controller configuration for a plugin artifact repository", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "keyFormat": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "configuration": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"name", "configuration"}, + }, + }, + } +} + func schema_pkg_apis_workflow_v1alpha1_PodGC(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ diff --git a/pkg/apis/workflow/v1alpha1/workflow_types.go b/pkg/apis/workflow/v1alpha1/workflow_types.go index 9ad89fb27817..93b6e9d035de 100644 --- a/pkg/apis/workflow/v1alpha1/workflow_types.go +++ b/pkg/apis/workflow/v1alpha1/workflow_types.go @@ -860,6 +860,75 @@ func (a Artifacts) GetArtifactByName(name string) *Artifact { return nil } +type ArtifactPluginLogs int + +const ( + IncludeLogs ArtifactPluginLogs = iota + ExcludeLogs +) + +func (a Artifacts) GetPluginNames(ctx context.Context, defaultRepo *ArtifactRepository, includeLogs ArtifactPluginLogs, archiveLocation *ArtifactLocation) []ArtifactPluginName { + log := logging.RequireLoggerFromContext(ctx) + plugins := make(map[ArtifactPluginName]bool, 0) + defaultPluginName := ArtifactPluginName("") + if defaultRepo != nil && + defaultRepo.Plugin != nil { + defaultPluginName = defaultRepo.Plugin.Name + } + + // Check if the template's archiveLocation specifies a plugin + archiveLocationPluginName := ArtifactPluginName("") + if archiveLocation != nil && archiveLocation.Plugin != nil { + archiveLocationPluginName = archiveLocation.Plugin.Name + log.WithFields(logging.Fields{"plugin": archiveLocationPluginName}).Debug(ctx, "template archiveLocation has plugin") + } + + for _, art := range a { + artifactPluginName := ArtifactPluginName("") + if art.Plugin != nil { + artifactPluginName = art.Plugin.Name + } + log.WithField("artifact", art).Debug(ctx, "checking artifact") + switch { + // if the artifact has a plugin name, add it + case artifactPluginName != "": + log.WithFields(logging.Fields{"plugin": artifactPluginName}).Debug(ctx, "adding plugin") + plugins[artifactPluginName] = true + // if the artifact has no plugin name but archiveLocation has a plugin, use that + case artifactPluginName == "" && archiveLocationPluginName != "": + log.WithFields(logging.Fields{"artifact": art, "plugin": archiveLocationPluginName}).Debug(ctx, "no plugin name, using archiveLocation plugin") + plugins[archiveLocationPluginName] = true + // if the artifact has no plugin name, but the default repo has a plugin name, add it. This is valid, for example an Input From. + case artifactPluginName == "" && + defaultPluginName != "": + log.WithFields(logging.Fields{"artifact": art, "defaultRepo": defaultRepo}).Debug(ctx, "no plugin name, using default repo plugin") + plugins[defaultPluginName] = true + // if the default repo has a plugin name, add it + case defaultPluginName != "": + log.WithFields(logging.Fields{"plugin": defaultPluginName}).Debug(ctx, "adding default repo plugin") + plugins[defaultPluginName] = true + default: + log.WithFields(logging.Fields{"artifact": art.Name, "defaultRepo": defaultRepo}).Debug(ctx, "no plugin") + } + } + // TODO separate this out into a separate function + if includeLogs == IncludeLogs && + defaultRepo != nil && + defaultRepo.ArchiveLogs != nil && + *defaultRepo.ArchiveLogs && + defaultRepo.Plugin != nil { + log.WithFields(logging.Fields{"plugin": defaultRepo.Plugin.Name}).Debug(ctx, "adding logging plugin") + plugins[defaultRepo.Plugin.Name] = true + } + pluginNames := make([]ArtifactPluginName, 0) + for name := range plugins { + if name != "" { + pluginNames = append(pluginNames, name) + } + } + return pluginNames +} + // Inputs are the mechanism for passing parameters, artifacts, volumes from one template to another type Inputs struct { // Parameters are a list of parameters passed as inputs @@ -1195,6 +1264,9 @@ type ArtifactLocation struct { // Azure contains Azure Storage artifact location details Azure *AzureArtifact `json:"azure,omitempty" protobuf:"bytes,10,opt,name=azure"` + + // Plugin contains plugin artifact location details + Plugin *PluginArtifact `json:"plugin,omitempty" protobuf:"bytes,11,opt,name=plugin"` } func (a *ArtifactLocation) Get() (ArtifactLocationType, error) { @@ -1218,6 +1290,8 @@ func (a *ArtifactLocation) Get() (ArtifactLocationType, error) { return a.Raw, nil } else if a.S3 != nil { return a.S3, nil + } else if a.Plugin != nil { + return a.Plugin, nil } return nil, fmt.Errorf("artifact storage is not configured; see the docs for setup instructions: https://argo-workflows.readthedocs.io/en/latest/configure-artifact-repository/") } @@ -1242,6 +1316,8 @@ func (a *ArtifactLocation) SetType(x ArtifactLocationType) error { a.Raw = &RawArtifact{} case *S3Artifact: a.S3 = &S3Artifact{} + case *PluginArtifact: + a.Plugin = &PluginArtifact{} default: return fmt.Errorf("set type not supported for type: %v", reflect.TypeOf(v)) } @@ -3085,6 +3161,63 @@ func (o *OSSArtifact) HasLocation() bool { return o != nil && o.Bucket != "" && o.Endpoint != "" && o.Key != "" } +// ArtifactPluginName is the name of an artifact plugin +type ArtifactPluginName string + +func (a ArtifactPluginName) SocketDir() string { + return `/tmp/artifact-plugins/` + string(a) +} + +func (a ArtifactPluginName) SocketPath() string { + return a.SocketDir() + "/socket" +} + +func (a ArtifactPluginName) volumeName() string { + return "artifact-plugin-" + string(a) +} + +func (a ArtifactPluginName) VolumeMount() apiv1.VolumeMount { + return apiv1.VolumeMount{ + Name: a.volumeName(), + MountPath: a.SocketDir(), + } +} + +func (a ArtifactPluginName) Volume() apiv1.Volume { + return apiv1.Volume{ + Name: a.volumeName(), + VolumeSource: apiv1.VolumeSource{ + EmptyDir: &apiv1.EmptyDirVolumeSource{}, + }, + } +} + +// PluginArtifact is the location of a plugin artifact +type PluginArtifact struct { + // Name is the name of the artifact driver plugin + Name ArtifactPluginName `json:"name" protobuf:"bytes,1,opt,name=name"` + // Configuration is the plugin defined configuration for the artifact driver plugin + Configuration string `json:"configuration" protobuf:"bytes,2,opt,name=configuration"` + // ConnectionTimeoutSeconds is the timeout for the artifact driver connection, 5 seconds if not set + ConnectionTimeoutSeconds int32 `json:"connectionTimeoutSeconds,omitempty" protobuf:"varint,3,opt,name=connectionTimeoutSeconds"` + + // Key is the path in the artifact repository where the artifact resides + Key string `json:"key" protobuf:"bytes,4,opt,name=key"` +} + +func (p *PluginArtifact) GetKey() (string, error) { + return p.Key, nil +} +func (p *PluginArtifact) SetKey(key string) error { + p.Key = key + return nil +} + +// HasLocation returns true if the plugin artifact has a name, configuration and key +func (p *PluginArtifact) HasLocation() bool { + return p != nil && p.Name != "" && p.Configuration != "" && p.Key != "" +} + // ExecutorConfig holds configurations of an executor container. type ExecutorConfig struct { // ServiceAccountName specifies the service account name of the executor container. diff --git a/pkg/apis/workflow/v1alpha1/workflow_types_test.go b/pkg/apis/workflow/v1alpha1/workflow_types_test.go index c46adbe2e4c5..1a032a70d577 100644 --- a/pkg/apis/workflow/v1alpha1/workflow_types_test.go +++ b/pkg/apis/workflow/v1alpha1/workflow_types_test.go @@ -518,6 +518,11 @@ func TestArtifactLocation_SetType(t *testing.T) { require.NoError(t, l.SetType(&AzureArtifact{})) assert.NotNil(t, l.Azure) }) + t.Run("Plugin", func(t *testing.T) { + l := &ArtifactLocation{} + require.NoError(t, l.SetType(&PluginArtifact{})) + assert.NotNil(t, l.Plugin) + }) } func TestArtifactLocation_Key(t *testing.T) { diff --git a/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go index dff3af87cc9d..9c7d0c85682c 100644 --- a/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/workflow/v1alpha1/zz_generated.deepcopy.go @@ -274,6 +274,11 @@ func (in *ArtifactLocation) DeepCopyInto(out *ArtifactLocation) { *out = new(AzureArtifact) (*in).DeepCopyInto(*out) } + if in.Plugin != nil { + in, out := &in.Plugin, &out.Plugin + *out = new(PluginArtifact) + **out = **in + } return } @@ -370,6 +375,11 @@ func (in *ArtifactRepository) DeepCopyInto(out *ArtifactRepository) { *out = new(AzureArtifactRepository) (*in).DeepCopyInto(*out) } + if in.Plugin != nil { + in, out := &in.Plugin, &out.Plugin + *out = new(PluginArtifactRepository) + **out = **in + } return } @@ -2524,6 +2534,38 @@ func (in *Plugin) DeepCopy() *Plugin { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PluginArtifact) DeepCopyInto(out *PluginArtifact) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PluginArtifact. +func (in *PluginArtifact) DeepCopy() *PluginArtifact { + if in == nil { + return nil + } + out := new(PluginArtifact) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PluginArtifactRepository) DeepCopyInto(out *PluginArtifactRepository) { + *out = *in + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PluginArtifactRepository. +func (in *PluginArtifactRepository) DeepCopy() *PluginArtifactRepository { + if in == nil { + return nil + } + out := new(PluginArtifactRepository) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PodGC) DeepCopyInto(out *PodGC) { *out = *in diff --git a/pkg/plugins/executor/swagger.yml b/pkg/plugins/executor/swagger.yml index 32d34ccd8248..aefd9a002cb9 100644 --- a/pkg/plugins/executor/swagger.yml +++ b/pkg/plugins/executor/swagger.yml @@ -155,6 +155,8 @@ definitions: path: description: Path is the container path to the artifact type: string + plugin: + $ref: '#/definitions/PluginArtifact' raw: $ref: '#/definitions/RawArtifact' recurseMode: @@ -203,6 +205,8 @@ definitions: $ref: '#/definitions/HTTPArtifact' oss: $ref: '#/definitions/OSSArtifact' + plugin: + $ref: '#/definitions/PluginArtifact' raw: $ref: '#/definitions/RawArtifact' s3: @@ -262,6 +266,8 @@ definitions: path: description: Path is the container path to the artifact type: string + plugin: + $ref: '#/definitions/PluginArtifact' raw: $ref: '#/definitions/RawArtifact' recurseMode: @@ -273,6 +279,9 @@ definitions: description: SubPath allows an artifact to be sourced from a subpath within the specified source type: string type: object + ArtifactPluginName: + description: ArtifactPluginName is the name of an artifact plugin + type: string ArtifactoryArtifact: description: ArtifactoryArtifact is the location of an artifactory artifact properties: @@ -2900,6 +2909,22 @@ definitions: Plugin: description: Plugin is an Object with exactly one key type: object + PluginArtifact: + description: PluginArtifact is the location of a plugin artifact + properties: + configuration: + description: Configuration is the plugin defined configuration for the artifact driver plugin + type: string + connectionTimeoutSeconds: + description: ConnectionTimeoutSeconds is the timeout for the artifact driver connection, 5 seconds if not set + format: int32 + type: integer + key: + description: Key is the path in the artifact repository where the artifact resides + type: string + name: + $ref: '#/definitions/ArtifactPluginName' + type: object PodAffinity: properties: preferredDuringSchedulingIgnoredDuringExecution: diff --git a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1Artifact.md b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1Artifact.md index 185ba5cb34d2..a625f4e92ecf 100644 --- a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1Artifact.md +++ b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1Artifact.md @@ -26,6 +26,7 @@ Name | Type | Description | Notes **optional** | **Boolean** | Make Artifacts optional, if Artifacts doesn't generate or exist | [optional] **oss** | [**IoArgoprojWorkflowV1alpha1OSSArtifact**](IoArgoprojWorkflowV1alpha1OSSArtifact.md) | | [optional] **path** | **String** | Path is the container path to the artifact | [optional] +**plugin** | [**IoArgoprojWorkflowV1alpha1PluginArtifact**](IoArgoprojWorkflowV1alpha1PluginArtifact.md) | | [optional] **raw** | [**IoArgoprojWorkflowV1alpha1RawArtifact**](IoArgoprojWorkflowV1alpha1RawArtifact.md) | | [optional] **recurseMode** | **Boolean** | If mode is set, apply the permission recursively into the artifact if it is a folder | [optional] **s3** | [**IoArgoprojWorkflowV1alpha1S3Artifact**](IoArgoprojWorkflowV1alpha1S3Artifact.md) | | [optional] diff --git a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactLocation.md b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactLocation.md index dd41fb581833..727093602c16 100644 --- a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactLocation.md +++ b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactLocation.md @@ -16,6 +16,7 @@ Name | Type | Description | Notes **hdfs** | [**IoArgoprojWorkflowV1alpha1HDFSArtifact**](IoArgoprojWorkflowV1alpha1HDFSArtifact.md) | | [optional] **http** | [**IoArgoprojWorkflowV1alpha1HTTPArtifact**](IoArgoprojWorkflowV1alpha1HTTPArtifact.md) | | [optional] **oss** | [**IoArgoprojWorkflowV1alpha1OSSArtifact**](IoArgoprojWorkflowV1alpha1OSSArtifact.md) | | [optional] +**plugin** | [**IoArgoprojWorkflowV1alpha1PluginArtifact**](IoArgoprojWorkflowV1alpha1PluginArtifact.md) | | [optional] **raw** | [**IoArgoprojWorkflowV1alpha1RawArtifact**](IoArgoprojWorkflowV1alpha1RawArtifact.md) | | [optional] **s3** | [**IoArgoprojWorkflowV1alpha1S3Artifact**](IoArgoprojWorkflowV1alpha1S3Artifact.md) | | [optional] diff --git a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactPaths.md b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactPaths.md index 1d879bf2a15a..322ae59d7b78 100644 --- a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactPaths.md +++ b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactPaths.md @@ -26,6 +26,7 @@ Name | Type | Description | Notes **optional** | **Boolean** | Make Artifacts optional, if Artifacts doesn't generate or exist | [optional] **oss** | [**IoArgoprojWorkflowV1alpha1OSSArtifact**](IoArgoprojWorkflowV1alpha1OSSArtifact.md) | | [optional] **path** | **String** | Path is the container path to the artifact | [optional] +**plugin** | [**IoArgoprojWorkflowV1alpha1PluginArtifact**](IoArgoprojWorkflowV1alpha1PluginArtifact.md) | | [optional] **raw** | [**IoArgoprojWorkflowV1alpha1RawArtifact**](IoArgoprojWorkflowV1alpha1RawArtifact.md) | | [optional] **recurseMode** | **Boolean** | If mode is set, apply the permission recursively into the artifact if it is a folder | [optional] **s3** | [**IoArgoprojWorkflowV1alpha1S3Artifact**](IoArgoprojWorkflowV1alpha1S3Artifact.md) | | [optional] diff --git a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactRepository.md b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactRepository.md index d3d53c665644..6ff38ed2f016 100644 --- a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactRepository.md +++ b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1ArtifactRepository.md @@ -14,6 +14,7 @@ Name | Type | Description | Notes **gcs** | [**IoArgoprojWorkflowV1alpha1GCSArtifactRepository**](IoArgoprojWorkflowV1alpha1GCSArtifactRepository.md) | | [optional] **hdfs** | [**IoArgoprojWorkflowV1alpha1HDFSArtifactRepository**](IoArgoprojWorkflowV1alpha1HDFSArtifactRepository.md) | | [optional] **oss** | [**IoArgoprojWorkflowV1alpha1OSSArtifactRepository**](IoArgoprojWorkflowV1alpha1OSSArtifactRepository.md) | | [optional] +**plugin** | [**IoArgoprojWorkflowV1alpha1PluginArtifactRepository**](IoArgoprojWorkflowV1alpha1PluginArtifactRepository.md) | | [optional] **s3** | [**IoArgoprojWorkflowV1alpha1S3ArtifactRepository**](IoArgoprojWorkflowV1alpha1S3ArtifactRepository.md) | | [optional] diff --git a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifact.md b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifact.md new file mode 100644 index 000000000000..001dd38807f2 --- /dev/null +++ b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifact.md @@ -0,0 +1,17 @@ + + +# IoArgoprojWorkflowV1alpha1PluginArtifact + +PluginArtifact is the location of a plugin artifact + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**_configuration** | **String** | Configuration is the plugin defined configuration for the artifact driver plugin | +**connectionTimeoutSeconds** | **Integer** | ConnectionTimeoutSeconds is the timeout for the artifact driver connection, 5 seconds if not set | [optional] +**key** | **String** | Key is the path in the artifact repository where the artifact resides | +**name** | **String** | Name is the name of the artifact driver plugin | + + + diff --git a/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifactRepository.md b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifactRepository.md new file mode 100644 index 000000000000..bc53f7e19dfa --- /dev/null +++ b/sdks/java/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifactRepository.md @@ -0,0 +1,16 @@ + + +# IoArgoprojWorkflowV1alpha1PluginArtifactRepository + +PluginArtifactRepository defines the controller configuration for a plugin artifact repository + +## Properties + +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**_configuration** | **String** | | +**keyFormat** | **String** | | [optional] +**name** | **String** | | + + + diff --git a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact.py b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact.py index 0f3b949ca659..4e22081722d6 100644 --- a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact.py +++ b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact.py @@ -39,6 +39,7 @@ def lazy_import(): from argo_workflows.model.io_argoproj_workflow_v1alpha1_hdfs_artifact import IoArgoprojWorkflowV1alpha1HDFSArtifact from argo_workflows.model.io_argoproj_workflow_v1alpha1_http_artifact import IoArgoprojWorkflowV1alpha1HTTPArtifact from argo_workflows.model.io_argoproj_workflow_v1alpha1_oss_artifact import IoArgoprojWorkflowV1alpha1OSSArtifact + from argo_workflows.model.io_argoproj_workflow_v1alpha1_plugin_artifact import IoArgoprojWorkflowV1alpha1PluginArtifact from argo_workflows.model.io_argoproj_workflow_v1alpha1_raw_artifact import IoArgoprojWorkflowV1alpha1RawArtifact from argo_workflows.model.io_argoproj_workflow_v1alpha1_s3_artifact import IoArgoprojWorkflowV1alpha1S3Artifact globals()['IoArgoprojWorkflowV1alpha1ArchiveStrategy'] = IoArgoprojWorkflowV1alpha1ArchiveStrategy @@ -50,6 +51,7 @@ def lazy_import(): globals()['IoArgoprojWorkflowV1alpha1HDFSArtifact'] = IoArgoprojWorkflowV1alpha1HDFSArtifact globals()['IoArgoprojWorkflowV1alpha1HTTPArtifact'] = IoArgoprojWorkflowV1alpha1HTTPArtifact globals()['IoArgoprojWorkflowV1alpha1OSSArtifact'] = IoArgoprojWorkflowV1alpha1OSSArtifact + globals()['IoArgoprojWorkflowV1alpha1PluginArtifact'] = IoArgoprojWorkflowV1alpha1PluginArtifact globals()['IoArgoprojWorkflowV1alpha1RawArtifact'] = IoArgoprojWorkflowV1alpha1RawArtifact globals()['IoArgoprojWorkflowV1alpha1S3Artifact'] = IoArgoprojWorkflowV1alpha1S3Artifact @@ -125,6 +127,7 @@ def openapi_types(): 'optional': (bool,), # noqa: E501 'oss': (IoArgoprojWorkflowV1alpha1OSSArtifact,), # noqa: E501 'path': (str,), # noqa: E501 + 'plugin': (IoArgoprojWorkflowV1alpha1PluginArtifact,), # noqa: E501 'raw': (IoArgoprojWorkflowV1alpha1RawArtifact,), # noqa: E501 'recurse_mode': (bool,), # noqa: E501 's3': (IoArgoprojWorkflowV1alpha1S3Artifact,), # noqa: E501 @@ -155,6 +158,7 @@ def discriminator(): 'optional': 'optional', # noqa: E501 'oss': 'oss', # noqa: E501 'path': 'path', # noqa: E501 + 'plugin': 'plugin', # noqa: E501 'raw': 'raw', # noqa: E501 'recurse_mode': 'recurseMode', # noqa: E501 's3': 's3', # noqa: E501 @@ -222,6 +226,7 @@ def _from_openapi_data(cls, name, *args, **kwargs): # noqa: E501 optional (bool): Make Artifacts optional, if Artifacts doesn't generate or exist. [optional] # noqa: E501 oss (IoArgoprojWorkflowV1alpha1OSSArtifact): [optional] # noqa: E501 path (str): Path is the container path to the artifact. [optional] # noqa: E501 + plugin (IoArgoprojWorkflowV1alpha1PluginArtifact): [optional] # noqa: E501 raw (IoArgoprojWorkflowV1alpha1RawArtifact): [optional] # noqa: E501 recurse_mode (bool): If mode is set, apply the permission recursively into the artifact if it is a folder. [optional] # noqa: E501 s3 (IoArgoprojWorkflowV1alpha1S3Artifact): [optional] # noqa: E501 @@ -328,6 +333,7 @@ def __init__(self, name, *args, **kwargs): # noqa: E501 optional (bool): Make Artifacts optional, if Artifacts doesn't generate or exist. [optional] # noqa: E501 oss (IoArgoprojWorkflowV1alpha1OSSArtifact): [optional] # noqa: E501 path (str): Path is the container path to the artifact. [optional] # noqa: E501 + plugin (IoArgoprojWorkflowV1alpha1PluginArtifact): [optional] # noqa: E501 raw (IoArgoprojWorkflowV1alpha1RawArtifact): [optional] # noqa: E501 recurse_mode (bool): If mode is set, apply the permission recursively into the artifact if it is a folder. [optional] # noqa: E501 s3 (IoArgoprojWorkflowV1alpha1S3Artifact): [optional] # noqa: E501 diff --git a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact_location.py b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact_location.py index ae0839bfa657..bb60a87a9139 100644 --- a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact_location.py +++ b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact_location.py @@ -37,6 +37,7 @@ def lazy_import(): from argo_workflows.model.io_argoproj_workflow_v1alpha1_hdfs_artifact import IoArgoprojWorkflowV1alpha1HDFSArtifact from argo_workflows.model.io_argoproj_workflow_v1alpha1_http_artifact import IoArgoprojWorkflowV1alpha1HTTPArtifact from argo_workflows.model.io_argoproj_workflow_v1alpha1_oss_artifact import IoArgoprojWorkflowV1alpha1OSSArtifact + from argo_workflows.model.io_argoproj_workflow_v1alpha1_plugin_artifact import IoArgoprojWorkflowV1alpha1PluginArtifact from argo_workflows.model.io_argoproj_workflow_v1alpha1_raw_artifact import IoArgoprojWorkflowV1alpha1RawArtifact from argo_workflows.model.io_argoproj_workflow_v1alpha1_s3_artifact import IoArgoprojWorkflowV1alpha1S3Artifact globals()['IoArgoprojWorkflowV1alpha1ArtifactoryArtifact'] = IoArgoprojWorkflowV1alpha1ArtifactoryArtifact @@ -46,6 +47,7 @@ def lazy_import(): globals()['IoArgoprojWorkflowV1alpha1HDFSArtifact'] = IoArgoprojWorkflowV1alpha1HDFSArtifact globals()['IoArgoprojWorkflowV1alpha1HTTPArtifact'] = IoArgoprojWorkflowV1alpha1HTTPArtifact globals()['IoArgoprojWorkflowV1alpha1OSSArtifact'] = IoArgoprojWorkflowV1alpha1OSSArtifact + globals()['IoArgoprojWorkflowV1alpha1PluginArtifact'] = IoArgoprojWorkflowV1alpha1PluginArtifact globals()['IoArgoprojWorkflowV1alpha1RawArtifact'] = IoArgoprojWorkflowV1alpha1RawArtifact globals()['IoArgoprojWorkflowV1alpha1S3Artifact'] = IoArgoprojWorkflowV1alpha1S3Artifact @@ -111,6 +113,7 @@ def openapi_types(): 'hdfs': (IoArgoprojWorkflowV1alpha1HDFSArtifact,), # noqa: E501 'http': (IoArgoprojWorkflowV1alpha1HTTPArtifact,), # noqa: E501 'oss': (IoArgoprojWorkflowV1alpha1OSSArtifact,), # noqa: E501 + 'plugin': (IoArgoprojWorkflowV1alpha1PluginArtifact,), # noqa: E501 'raw': (IoArgoprojWorkflowV1alpha1RawArtifact,), # noqa: E501 's3': (IoArgoprojWorkflowV1alpha1S3Artifact,), # noqa: E501 } @@ -129,6 +132,7 @@ def discriminator(): 'hdfs': 'hdfs', # noqa: E501 'http': 'http', # noqa: E501 'oss': 'oss', # noqa: E501 + 'plugin': 'plugin', # noqa: E501 'raw': 'raw', # noqa: E501 's3': 's3', # noqa: E501 } @@ -182,6 +186,7 @@ def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 hdfs (IoArgoprojWorkflowV1alpha1HDFSArtifact): [optional] # noqa: E501 http (IoArgoprojWorkflowV1alpha1HTTPArtifact): [optional] # noqa: E501 oss (IoArgoprojWorkflowV1alpha1OSSArtifact): [optional] # noqa: E501 + plugin (IoArgoprojWorkflowV1alpha1PluginArtifact): [optional] # noqa: E501 raw (IoArgoprojWorkflowV1alpha1RawArtifact): [optional] # noqa: E501 s3 (IoArgoprojWorkflowV1alpha1S3Artifact): [optional] # noqa: E501 """ @@ -273,6 +278,7 @@ def __init__(self, *args, **kwargs): # noqa: E501 hdfs (IoArgoprojWorkflowV1alpha1HDFSArtifact): [optional] # noqa: E501 http (IoArgoprojWorkflowV1alpha1HTTPArtifact): [optional] # noqa: E501 oss (IoArgoprojWorkflowV1alpha1OSSArtifact): [optional] # noqa: E501 + plugin (IoArgoprojWorkflowV1alpha1PluginArtifact): [optional] # noqa: E501 raw (IoArgoprojWorkflowV1alpha1RawArtifact): [optional] # noqa: E501 s3 (IoArgoprojWorkflowV1alpha1S3Artifact): [optional] # noqa: E501 """ diff --git a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact_paths.py b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact_paths.py index ff235ad19c04..b651aae000d1 100644 --- a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact_paths.py +++ b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact_paths.py @@ -39,6 +39,7 @@ def lazy_import(): from argo_workflows.model.io_argoproj_workflow_v1alpha1_hdfs_artifact import IoArgoprojWorkflowV1alpha1HDFSArtifact from argo_workflows.model.io_argoproj_workflow_v1alpha1_http_artifact import IoArgoprojWorkflowV1alpha1HTTPArtifact from argo_workflows.model.io_argoproj_workflow_v1alpha1_oss_artifact import IoArgoprojWorkflowV1alpha1OSSArtifact + from argo_workflows.model.io_argoproj_workflow_v1alpha1_plugin_artifact import IoArgoprojWorkflowV1alpha1PluginArtifact from argo_workflows.model.io_argoproj_workflow_v1alpha1_raw_artifact import IoArgoprojWorkflowV1alpha1RawArtifact from argo_workflows.model.io_argoproj_workflow_v1alpha1_s3_artifact import IoArgoprojWorkflowV1alpha1S3Artifact globals()['IoArgoprojWorkflowV1alpha1ArchiveStrategy'] = IoArgoprojWorkflowV1alpha1ArchiveStrategy @@ -50,6 +51,7 @@ def lazy_import(): globals()['IoArgoprojWorkflowV1alpha1HDFSArtifact'] = IoArgoprojWorkflowV1alpha1HDFSArtifact globals()['IoArgoprojWorkflowV1alpha1HTTPArtifact'] = IoArgoprojWorkflowV1alpha1HTTPArtifact globals()['IoArgoprojWorkflowV1alpha1OSSArtifact'] = IoArgoprojWorkflowV1alpha1OSSArtifact + globals()['IoArgoprojWorkflowV1alpha1PluginArtifact'] = IoArgoprojWorkflowV1alpha1PluginArtifact globals()['IoArgoprojWorkflowV1alpha1RawArtifact'] = IoArgoprojWorkflowV1alpha1RawArtifact globals()['IoArgoprojWorkflowV1alpha1S3Artifact'] = IoArgoprojWorkflowV1alpha1S3Artifact @@ -125,6 +127,7 @@ def openapi_types(): 'optional': (bool,), # noqa: E501 'oss': (IoArgoprojWorkflowV1alpha1OSSArtifact,), # noqa: E501 'path': (str,), # noqa: E501 + 'plugin': (IoArgoprojWorkflowV1alpha1PluginArtifact,), # noqa: E501 'raw': (IoArgoprojWorkflowV1alpha1RawArtifact,), # noqa: E501 'recurse_mode': (bool,), # noqa: E501 's3': (IoArgoprojWorkflowV1alpha1S3Artifact,), # noqa: E501 @@ -155,6 +158,7 @@ def discriminator(): 'optional': 'optional', # noqa: E501 'oss': 'oss', # noqa: E501 'path': 'path', # noqa: E501 + 'plugin': 'plugin', # noqa: E501 'raw': 'raw', # noqa: E501 'recurse_mode': 'recurseMode', # noqa: E501 's3': 's3', # noqa: E501 @@ -222,6 +226,7 @@ def _from_openapi_data(cls, name, *args, **kwargs): # noqa: E501 optional (bool): Make Artifacts optional, if Artifacts doesn't generate or exist. [optional] # noqa: E501 oss (IoArgoprojWorkflowV1alpha1OSSArtifact): [optional] # noqa: E501 path (str): Path is the container path to the artifact. [optional] # noqa: E501 + plugin (IoArgoprojWorkflowV1alpha1PluginArtifact): [optional] # noqa: E501 raw (IoArgoprojWorkflowV1alpha1RawArtifact): [optional] # noqa: E501 recurse_mode (bool): If mode is set, apply the permission recursively into the artifact if it is a folder. [optional] # noqa: E501 s3 (IoArgoprojWorkflowV1alpha1S3Artifact): [optional] # noqa: E501 @@ -328,6 +333,7 @@ def __init__(self, name, *args, **kwargs): # noqa: E501 optional (bool): Make Artifacts optional, if Artifacts doesn't generate or exist. [optional] # noqa: E501 oss (IoArgoprojWorkflowV1alpha1OSSArtifact): [optional] # noqa: E501 path (str): Path is the container path to the artifact. [optional] # noqa: E501 + plugin (IoArgoprojWorkflowV1alpha1PluginArtifact): [optional] # noqa: E501 raw (IoArgoprojWorkflowV1alpha1RawArtifact): [optional] # noqa: E501 recurse_mode (bool): If mode is set, apply the permission recursively into the artifact if it is a folder. [optional] # noqa: E501 s3 (IoArgoprojWorkflowV1alpha1S3Artifact): [optional] # noqa: E501 diff --git a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact_repository.py b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact_repository.py index 7e8fede73e29..f4f2112b92b1 100644 --- a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact_repository.py +++ b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_artifact_repository.py @@ -35,12 +35,14 @@ def lazy_import(): from argo_workflows.model.io_argoproj_workflow_v1alpha1_gcs_artifact_repository import IoArgoprojWorkflowV1alpha1GCSArtifactRepository from argo_workflows.model.io_argoproj_workflow_v1alpha1_hdfs_artifact_repository import IoArgoprojWorkflowV1alpha1HDFSArtifactRepository from argo_workflows.model.io_argoproj_workflow_v1alpha1_oss_artifact_repository import IoArgoprojWorkflowV1alpha1OSSArtifactRepository + from argo_workflows.model.io_argoproj_workflow_v1alpha1_plugin_artifact_repository import IoArgoprojWorkflowV1alpha1PluginArtifactRepository from argo_workflows.model.io_argoproj_workflow_v1alpha1_s3_artifact_repository import IoArgoprojWorkflowV1alpha1S3ArtifactRepository globals()['IoArgoprojWorkflowV1alpha1ArtifactoryArtifactRepository'] = IoArgoprojWorkflowV1alpha1ArtifactoryArtifactRepository globals()['IoArgoprojWorkflowV1alpha1AzureArtifactRepository'] = IoArgoprojWorkflowV1alpha1AzureArtifactRepository globals()['IoArgoprojWorkflowV1alpha1GCSArtifactRepository'] = IoArgoprojWorkflowV1alpha1GCSArtifactRepository globals()['IoArgoprojWorkflowV1alpha1HDFSArtifactRepository'] = IoArgoprojWorkflowV1alpha1HDFSArtifactRepository globals()['IoArgoprojWorkflowV1alpha1OSSArtifactRepository'] = IoArgoprojWorkflowV1alpha1OSSArtifactRepository + globals()['IoArgoprojWorkflowV1alpha1PluginArtifactRepository'] = IoArgoprojWorkflowV1alpha1PluginArtifactRepository globals()['IoArgoprojWorkflowV1alpha1S3ArtifactRepository'] = IoArgoprojWorkflowV1alpha1S3ArtifactRepository @@ -103,6 +105,7 @@ def openapi_types(): 'gcs': (IoArgoprojWorkflowV1alpha1GCSArtifactRepository,), # noqa: E501 'hdfs': (IoArgoprojWorkflowV1alpha1HDFSArtifactRepository,), # noqa: E501 'oss': (IoArgoprojWorkflowV1alpha1OSSArtifactRepository,), # noqa: E501 + 'plugin': (IoArgoprojWorkflowV1alpha1PluginArtifactRepository,), # noqa: E501 's3': (IoArgoprojWorkflowV1alpha1S3ArtifactRepository,), # noqa: E501 } @@ -118,6 +121,7 @@ def discriminator(): 'gcs': 'gcs', # noqa: E501 'hdfs': 'hdfs', # noqa: E501 'oss': 'oss', # noqa: E501 + 'plugin': 'plugin', # noqa: E501 's3': 's3', # noqa: E501 } @@ -168,6 +172,7 @@ def _from_openapi_data(cls, *args, **kwargs): # noqa: E501 gcs (IoArgoprojWorkflowV1alpha1GCSArtifactRepository): [optional] # noqa: E501 hdfs (IoArgoprojWorkflowV1alpha1HDFSArtifactRepository): [optional] # noqa: E501 oss (IoArgoprojWorkflowV1alpha1OSSArtifactRepository): [optional] # noqa: E501 + plugin (IoArgoprojWorkflowV1alpha1PluginArtifactRepository): [optional] # noqa: E501 s3 (IoArgoprojWorkflowV1alpha1S3ArtifactRepository): [optional] # noqa: E501 """ @@ -256,6 +261,7 @@ def __init__(self, *args, **kwargs): # noqa: E501 gcs (IoArgoprojWorkflowV1alpha1GCSArtifactRepository): [optional] # noqa: E501 hdfs (IoArgoprojWorkflowV1alpha1HDFSArtifactRepository): [optional] # noqa: E501 oss (IoArgoprojWorkflowV1alpha1OSSArtifactRepository): [optional] # noqa: E501 + plugin (IoArgoprojWorkflowV1alpha1PluginArtifactRepository): [optional] # noqa: E501 s3 (IoArgoprojWorkflowV1alpha1S3ArtifactRepository): [optional] # noqa: E501 """ diff --git a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_plugin_artifact.py b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_plugin_artifact.py new file mode 100644 index 000000000000..6e802cd3d7aa --- /dev/null +++ b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_plugin_artifact.py @@ -0,0 +1,277 @@ +""" + Argo Workflows API + + Argo Workflows is an open source container-native workflow engine for orchestrating parallel jobs on Kubernetes. For more information, please see https://argo-workflows.readthedocs.io/en/latest/ # noqa: E501 + + The version of the OpenAPI document: VERSION + Generated by: https://openapi-generator.tech +""" + + +import re # noqa: F401 +import sys # noqa: F401 + +from argo_workflows.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, + OpenApiModel +) +from argo_workflows.exceptions import ApiAttributeError + + + +class IoArgoprojWorkflowV1alpha1PluginArtifact(ModelNormal): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + } + + validations = { + } + + @cached_property + def additional_properties_type(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + """ + return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501 + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + return { + 'configuration': (str,), # noqa: E501 + 'key': (str,), # noqa: E501 + 'name': (str,), # noqa: E501 + 'connection_timeout_seconds': (int,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + + attribute_map = { + 'configuration': 'configuration', # noqa: E501 + 'key': 'key', # noqa: E501 + 'name': 'name', # noqa: E501 + 'connection_timeout_seconds': 'connectionTimeoutSeconds', # noqa: E501 + } + + read_only_vars = { + } + + _composed_schemas = {} + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, configuration, key, name, *args, **kwargs): # noqa: E501 + """IoArgoprojWorkflowV1alpha1PluginArtifact - a model defined in OpenAPI + + Args: + configuration (str): Configuration is the plugin defined configuration for the artifact driver plugin + key (str): Key is the path in the artifact repository where the artifact resides + name (str): Name is the name of the artifact driver plugin + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + connection_timeout_seconds (int): ConnectionTimeoutSeconds is the timeout for the artifact driver connection, 5 seconds if not set. [optional] # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.configuration = configuration + self.key = key + self.name = name + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + return self + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + ]) + + @convert_js_args_to_python_args + def __init__(self, configuration, key, name, *args, **kwargs): # noqa: E501 + """IoArgoprojWorkflowV1alpha1PluginArtifact - a model defined in OpenAPI + + Args: + configuration (str): Configuration is the plugin defined configuration for the artifact driver plugin + key (str): Key is the path in the artifact repository where the artifact resides + name (str): Name is the name of the artifact driver plugin + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + connection_timeout_seconds (int): ConnectionTimeoutSeconds is the timeout for the artifact driver connection, 5 seconds if not set. [optional] # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.configuration = configuration + self.key = key + self.name = name + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + if var_name in self.read_only_vars: + raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate " + f"class with read only attributes.") diff --git a/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_plugin_artifact_repository.py b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_plugin_artifact_repository.py new file mode 100644 index 000000000000..87b456ea4286 --- /dev/null +++ b/sdks/python/client/argo_workflows/model/io_argoproj_workflow_v1alpha1_plugin_artifact_repository.py @@ -0,0 +1,271 @@ +""" + Argo Workflows API + + Argo Workflows is an open source container-native workflow engine for orchestrating parallel jobs on Kubernetes. For more information, please see https://argo-workflows.readthedocs.io/en/latest/ # noqa: E501 + + The version of the OpenAPI document: VERSION + Generated by: https://openapi-generator.tech +""" + + +import re # noqa: F401 +import sys # noqa: F401 + +from argo_workflows.model_utils import ( # noqa: F401 + ApiTypeError, + ModelComposed, + ModelNormal, + ModelSimple, + cached_property, + change_keys_js_to_python, + convert_js_args_to_python_args, + date, + datetime, + file_type, + none_type, + validate_get_composed_info, + OpenApiModel +) +from argo_workflows.exceptions import ApiAttributeError + + + +class IoArgoprojWorkflowV1alpha1PluginArtifactRepository(ModelNormal): + """NOTE: This class is auto generated by OpenAPI Generator. + Ref: https://openapi-generator.tech + + Do not edit the class manually. + + Attributes: + allowed_values (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + with a capitalized key describing the allowed value and an allowed + value. These dicts store the allowed enum values. + attribute_map (dict): The key is attribute name + and the value is json key in definition. + discriminator_value_class_map (dict): A dict to go from the discriminator + variable value to the discriminator class name. + validations (dict): The key is the tuple path to the attribute + and the for var_name this is (var_name,). The value is a dict + that stores validations for max_length, min_length, max_items, + min_items, exclusive_maximum, inclusive_maximum, exclusive_minimum, + inclusive_minimum, and regex. + additional_properties_type (tuple): A tuple of classes accepted + as additional properties values. + """ + + allowed_values = { + } + + validations = { + } + + @cached_property + def additional_properties_type(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + """ + return (bool, date, datetime, dict, float, int, list, str, none_type,) # noqa: E501 + + _nullable = False + + @cached_property + def openapi_types(): + """ + This must be a method because a model may have properties that are + of type self, this must run after the class is loaded + + Returns + openapi_types (dict): The key is attribute name + and the value is attribute type. + """ + return { + 'configuration': (str,), # noqa: E501 + 'name': (str,), # noqa: E501 + 'key_format': (str,), # noqa: E501 + } + + @cached_property + def discriminator(): + return None + + + attribute_map = { + 'configuration': 'configuration', # noqa: E501 + 'name': 'name', # noqa: E501 + 'key_format': 'keyFormat', # noqa: E501 + } + + read_only_vars = { + } + + _composed_schemas = {} + + @classmethod + @convert_js_args_to_python_args + def _from_openapi_data(cls, configuration, name, *args, **kwargs): # noqa: E501 + """IoArgoprojWorkflowV1alpha1PluginArtifactRepository - a model defined in OpenAPI + + Args: + configuration (str): + name (str): + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + key_format (str): [optional] # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + self = super(OpenApiModel, cls).__new__(cls) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.configuration = configuration + self.name = name + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + return self + + required_properties = set([ + '_data_store', + '_check_type', + '_spec_property_naming', + '_path_to_item', + '_configuration', + '_visited_composed_classes', + ]) + + @convert_js_args_to_python_args + def __init__(self, configuration, name, *args, **kwargs): # noqa: E501 + """IoArgoprojWorkflowV1alpha1PluginArtifactRepository - a model defined in OpenAPI + + Args: + configuration (str): + name (str): + + Keyword Args: + _check_type (bool): if True, values for parameters in openapi_types + will be type checked and a TypeError will be + raised if the wrong type is input. + Defaults to True + _path_to_item (tuple/list): This is a list of keys or values to + drill down to the model in received_data + when deserializing a response + _spec_property_naming (bool): True if the variable names in the input data + are serialized names, as specified in the OpenAPI document. + False if the variable names in the input data + are pythonic names, e.g. snake case (default) + _configuration (Configuration): the instance to use when + deserializing a file_type parameter. + If passed, type conversion is attempted + If omitted no type conversion is done. + _visited_composed_classes (tuple): This stores a tuple of + classes that we have traveled through so that + if we see that class again we will not use its + discriminator again. + When traveling through a discriminator, the + composed schema that is + is traveled through is added to this set. + For example if Animal has a discriminator + petType and we pass in "Dog", and the class Dog + allOf includes Animal, we move through Animal + once using the discriminator, and pick Dog. + Then in Dog, we will make an instance of the + Animal class but this time we won't travel + through its discriminator because we passed in + _visited_composed_classes = (Animal,) + key_format (str): [optional] # noqa: E501 + """ + + _check_type = kwargs.pop('_check_type', True) + _spec_property_naming = kwargs.pop('_spec_property_naming', False) + _path_to_item = kwargs.pop('_path_to_item', ()) + _configuration = kwargs.pop('_configuration', None) + _visited_composed_classes = kwargs.pop('_visited_composed_classes', ()) + + if args: + raise ApiTypeError( + "Invalid positional arguments=%s passed to %s. Remove those invalid positional arguments." % ( + args, + self.__class__.__name__, + ), + path_to_item=_path_to_item, + valid_classes=(self.__class__,), + ) + + self._data_store = {} + self._check_type = _check_type + self._spec_property_naming = _spec_property_naming + self._path_to_item = _path_to_item + self._configuration = _configuration + self._visited_composed_classes = _visited_composed_classes + (self.__class__,) + + self.configuration = configuration + self.name = name + for var_name, var_value in kwargs.items(): + if var_name not in self.attribute_map and \ + self._configuration is not None and \ + self._configuration.discard_unknown_keys and \ + self.additional_properties_type is None: + # discard variable. + continue + setattr(self, var_name, var_value) + if var_name in self.read_only_vars: + raise ApiAttributeError(f"`{var_name}` is a read-only attribute. Use `from_openapi_data` to instantiate " + f"class with read only attributes.") diff --git a/sdks/python/client/argo_workflows/models/__init__.py b/sdks/python/client/argo_workflows/models/__init__.py index cec1ab55d4ee..ea18d94c3a16 100644 --- a/sdks/python/client/argo_workflows/models/__init__.py +++ b/sdks/python/client/argo_workflows/models/__init__.py @@ -267,6 +267,8 @@ from argo_workflows.model.io_argoproj_workflow_v1alpha1_outputs import IoArgoprojWorkflowV1alpha1Outputs from argo_workflows.model.io_argoproj_workflow_v1alpha1_parallel_steps import IoArgoprojWorkflowV1alpha1ParallelSteps from argo_workflows.model.io_argoproj_workflow_v1alpha1_parameter import IoArgoprojWorkflowV1alpha1Parameter +from argo_workflows.model.io_argoproj_workflow_v1alpha1_plugin_artifact import IoArgoprojWorkflowV1alpha1PluginArtifact +from argo_workflows.model.io_argoproj_workflow_v1alpha1_plugin_artifact_repository import IoArgoprojWorkflowV1alpha1PluginArtifactRepository from argo_workflows.model.io_argoproj_workflow_v1alpha1_pod_gc import IoArgoprojWorkflowV1alpha1PodGC from argo_workflows.model.io_argoproj_workflow_v1alpha1_prometheus import IoArgoprojWorkflowV1alpha1Prometheus from argo_workflows.model.io_argoproj_workflow_v1alpha1_raw_artifact import IoArgoprojWorkflowV1alpha1RawArtifact diff --git a/sdks/python/client/docs/ClusterWorkflowTemplateServiceApi.md b/sdks/python/client/docs/ClusterWorkflowTemplateServiceApi.md index 11e1dd3bf43c..387ea9fa95af 100644 --- a/sdks/python/client/docs/ClusterWorkflowTemplateServiceApi.md +++ b/sdks/python/client/docs/ClusterWorkflowTemplateServiceApi.md @@ -539,6 +539,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -858,6 +864,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -1543,6 +1555,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -2410,6 +2428,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -2699,6 +2723,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -3010,6 +3040,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -3601,6 +3637,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -3932,6 +3974,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -4223,6 +4271,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -5129,6 +5183,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -5414,6 +5474,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -6381,6 +6447,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -7248,6 +7320,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -7537,6 +7615,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -7848,6 +7932,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -8439,6 +8529,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -8770,6 +8866,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -9061,6 +9163,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -9967,6 +10075,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -10252,6 +10366,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -12116,6 +12236,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -12435,6 +12561,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -13120,6 +13252,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -13987,6 +14125,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -14276,6 +14420,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -14587,6 +14737,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -15178,6 +15334,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -15509,6 +15671,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -15800,6 +15968,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -16706,6 +16880,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -16991,6 +17171,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -17958,6 +18144,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -18825,6 +19017,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -19114,6 +19312,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -19425,6 +19629,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -20016,6 +20226,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -20347,6 +20563,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -20638,6 +20860,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -21544,6 +21772,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -21829,6 +22063,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -23597,6 +23837,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -23916,6 +24162,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -24601,6 +24853,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -25468,6 +25726,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -25757,6 +26021,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -26068,6 +26338,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -26659,6 +26935,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -26990,6 +27272,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -27281,6 +27569,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -28187,6 +28481,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -28472,6 +28772,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -29439,6 +29745,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -30306,6 +30618,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -30595,6 +30913,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -30906,6 +31230,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -31497,6 +31827,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -31828,6 +32164,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -32119,6 +32461,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -33025,6 +33373,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -33310,6 +33664,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), diff --git a/sdks/python/client/docs/CronWorkflowServiceApi.md b/sdks/python/client/docs/CronWorkflowServiceApi.md index ebf537c4e672..df88d34d1f36 100644 --- a/sdks/python/client/docs/CronWorkflowServiceApi.md +++ b/sdks/python/client/docs/CronWorkflowServiceApi.md @@ -599,6 +599,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -918,6 +924,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -1603,6 +1615,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -2470,6 +2488,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -2759,6 +2783,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -3070,6 +3100,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -3661,6 +3697,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -3992,6 +4034,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -4283,6 +4331,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -5189,6 +5243,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -5474,6 +5534,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -6441,6 +6507,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -7308,6 +7380,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -7597,6 +7675,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -7908,6 +7992,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -8499,6 +8589,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -8830,6 +8926,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -9121,6 +9223,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -10027,6 +10135,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -10312,6 +10426,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -12258,6 +12378,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -12577,6 +12703,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -13262,6 +13394,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -14129,6 +14267,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -14418,6 +14562,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -14729,6 +14879,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -15320,6 +15476,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -15651,6 +15813,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -15942,6 +16110,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -16848,6 +17022,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -17133,6 +17313,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -18100,6 +18286,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -18967,6 +19159,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -19256,6 +19454,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -19567,6 +19771,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -20158,6 +20368,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -20489,6 +20705,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -20780,6 +21002,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -21686,6 +21914,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -21971,6 +22205,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -24002,6 +24242,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -24321,6 +24567,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -25006,6 +25258,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -25873,6 +26131,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -26162,6 +26426,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -26473,6 +26743,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -27064,6 +27340,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -27395,6 +27677,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -27686,6 +27974,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -28592,6 +28886,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -28877,6 +29177,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -29844,6 +30150,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -30711,6 +31023,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -31000,6 +31318,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -31311,6 +31635,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -31902,6 +32232,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -32233,6 +32569,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -32524,6 +32866,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -33430,6 +33778,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -33715,6 +34069,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), diff --git a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1Artifact.md b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1Artifact.md index 84af08865d9e..98571ff0621e 100644 --- a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1Artifact.md +++ b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1Artifact.md @@ -23,6 +23,7 @@ Name | Type | Description | Notes **optional** | **bool** | Make Artifacts optional, if Artifacts doesn't generate or exist | [optional] **oss** | [**IoArgoprojWorkflowV1alpha1OSSArtifact**](IoArgoprojWorkflowV1alpha1OSSArtifact.md) | | [optional] **path** | **str** | Path is the container path to the artifact | [optional] +**plugin** | [**IoArgoprojWorkflowV1alpha1PluginArtifact**](IoArgoprojWorkflowV1alpha1PluginArtifact.md) | | [optional] **raw** | [**IoArgoprojWorkflowV1alpha1RawArtifact**](IoArgoprojWorkflowV1alpha1RawArtifact.md) | | [optional] **recurse_mode** | **bool** | If mode is set, apply the permission recursively into the artifact if it is a folder | [optional] **s3** | [**IoArgoprojWorkflowV1alpha1S3Artifact**](IoArgoprojWorkflowV1alpha1S3Artifact.md) | | [optional] diff --git a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1ArtifactLocation.md b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1ArtifactLocation.md index e2e4949deb82..e428e1e279e0 100644 --- a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1ArtifactLocation.md +++ b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1ArtifactLocation.md @@ -13,6 +13,7 @@ Name | Type | Description | Notes **hdfs** | [**IoArgoprojWorkflowV1alpha1HDFSArtifact**](IoArgoprojWorkflowV1alpha1HDFSArtifact.md) | | [optional] **http** | [**IoArgoprojWorkflowV1alpha1HTTPArtifact**](IoArgoprojWorkflowV1alpha1HTTPArtifact.md) | | [optional] **oss** | [**IoArgoprojWorkflowV1alpha1OSSArtifact**](IoArgoprojWorkflowV1alpha1OSSArtifact.md) | | [optional] +**plugin** | [**IoArgoprojWorkflowV1alpha1PluginArtifact**](IoArgoprojWorkflowV1alpha1PluginArtifact.md) | | [optional] **raw** | [**IoArgoprojWorkflowV1alpha1RawArtifact**](IoArgoprojWorkflowV1alpha1RawArtifact.md) | | [optional] **s3** | [**IoArgoprojWorkflowV1alpha1S3Artifact**](IoArgoprojWorkflowV1alpha1S3Artifact.md) | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] diff --git a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1ArtifactPaths.md b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1ArtifactPaths.md index 25fe6ad26855..1964e3f9f9dc 100644 --- a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1ArtifactPaths.md +++ b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1ArtifactPaths.md @@ -23,6 +23,7 @@ Name | Type | Description | Notes **optional** | **bool** | Make Artifacts optional, if Artifacts doesn't generate or exist | [optional] **oss** | [**IoArgoprojWorkflowV1alpha1OSSArtifact**](IoArgoprojWorkflowV1alpha1OSSArtifact.md) | | [optional] **path** | **str** | Path is the container path to the artifact | [optional] +**plugin** | [**IoArgoprojWorkflowV1alpha1PluginArtifact**](IoArgoprojWorkflowV1alpha1PluginArtifact.md) | | [optional] **raw** | [**IoArgoprojWorkflowV1alpha1RawArtifact**](IoArgoprojWorkflowV1alpha1RawArtifact.md) | | [optional] **recurse_mode** | **bool** | If mode is set, apply the permission recursively into the artifact if it is a folder | [optional] **s3** | [**IoArgoprojWorkflowV1alpha1S3Artifact**](IoArgoprojWorkflowV1alpha1S3Artifact.md) | | [optional] diff --git a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1ArtifactRepository.md b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1ArtifactRepository.md index c5db3c661979..9f5463df1dc5 100644 --- a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1ArtifactRepository.md +++ b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1ArtifactRepository.md @@ -11,6 +11,7 @@ Name | Type | Description | Notes **gcs** | [**IoArgoprojWorkflowV1alpha1GCSArtifactRepository**](IoArgoprojWorkflowV1alpha1GCSArtifactRepository.md) | | [optional] **hdfs** | [**IoArgoprojWorkflowV1alpha1HDFSArtifactRepository**](IoArgoprojWorkflowV1alpha1HDFSArtifactRepository.md) | | [optional] **oss** | [**IoArgoprojWorkflowV1alpha1OSSArtifactRepository**](IoArgoprojWorkflowV1alpha1OSSArtifactRepository.md) | | [optional] +**plugin** | [**IoArgoprojWorkflowV1alpha1PluginArtifactRepository**](IoArgoprojWorkflowV1alpha1PluginArtifactRepository.md) | | [optional] **s3** | [**IoArgoprojWorkflowV1alpha1S3ArtifactRepository**](IoArgoprojWorkflowV1alpha1S3ArtifactRepository.md) | | [optional] **any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] diff --git a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifact.md b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifact.md new file mode 100644 index 000000000000..ff9142ed0a24 --- /dev/null +++ b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifact.md @@ -0,0 +1,16 @@ +# IoArgoprojWorkflowV1alpha1PluginArtifact + +PluginArtifact is the location of a plugin artifact + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**configuration** | **str** | Configuration is the plugin defined configuration for the artifact driver plugin | +**key** | **str** | Key is the path in the artifact repository where the artifact resides | +**name** | **str** | Name is the name of the artifact driver plugin | +**connection_timeout_seconds** | **int** | ConnectionTimeoutSeconds is the timeout for the artifact driver connection, 5 seconds if not set | [optional] +**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifactRepository.md b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifactRepository.md new file mode 100644 index 000000000000..9d04ce1b8856 --- /dev/null +++ b/sdks/python/client/docs/IoArgoprojWorkflowV1alpha1PluginArtifactRepository.md @@ -0,0 +1,15 @@ +# IoArgoprojWorkflowV1alpha1PluginArtifactRepository + +PluginArtifactRepository defines the controller configuration for a plugin artifact repository + +## Properties +Name | Type | Description | Notes +------------ | ------------- | ------------- | ------------- +**configuration** | **str** | | +**name** | **str** | | +**key_format** | **str** | | [optional] +**any string name** | **bool, date, datetime, dict, float, int, list, str, none_type** | any string name can be used but the value must be the correct type | [optional] + +[[Back to Model list]](../README.md#documentation-for-models) [[Back to API list]](../README.md#documentation-for-api-endpoints) [[Back to README]](../README.md) + + diff --git a/sdks/python/client/docs/WorkflowServiceApi.md b/sdks/python/client/docs/WorkflowServiceApi.md index 3c9595afacc9..741c9bd32da6 100644 --- a/sdks/python/client/docs/WorkflowServiceApi.md +++ b/sdks/python/client/docs/WorkflowServiceApi.md @@ -554,6 +554,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -873,6 +879,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -1558,6 +1570,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -2425,6 +2443,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -2714,6 +2738,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -3025,6 +3055,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -3616,6 +3652,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -3947,6 +3989,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -4238,6 +4286,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -5144,6 +5198,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -5429,6 +5489,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -6396,6 +6462,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -7263,6 +7335,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -7552,6 +7630,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -7863,6 +7947,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -8454,6 +8544,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -8785,6 +8881,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -9076,6 +9178,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -9982,6 +10090,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -10267,6 +10381,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -11472,6 +11592,11 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifactRepository( + configuration="configuration_example", + key_format="key_format_example", + name="name_example", + ), s3=IoArgoprojWorkflowV1alpha1S3ArtifactRepository( access_key_secret=SecretKeySelector( key="key_example", @@ -11746,6 +11871,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -12039,6 +12170,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -12342,6 +12479,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -13233,6 +13376,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -14100,6 +14249,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -14389,6 +14544,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -14700,6 +14861,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -15291,6 +15458,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -15622,6 +15795,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -15913,6 +16092,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -16819,6 +17004,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -17104,6 +17295,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -18098,6 +18295,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -18417,6 +18620,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -19102,6 +19311,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -19969,6 +20184,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -20258,6 +20479,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -20569,6 +20796,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -21160,6 +21393,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -21491,6 +21730,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -21782,6 +22027,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -22688,6 +22939,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -22973,6 +23230,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -23940,6 +24203,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -24807,6 +25076,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -25096,6 +25371,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -25407,6 +25688,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -25998,6 +26285,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -26329,6 +26622,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -26620,6 +26919,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -27526,6 +27831,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -27811,6 +28122,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -29717,6 +30034,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -30036,6 +30359,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -30721,6 +31050,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -31588,6 +31923,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -31877,6 +32218,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -32188,6 +32535,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -32779,6 +33132,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -33110,6 +33469,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -33401,6 +33766,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -34307,6 +34678,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -34592,6 +34969,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -35559,6 +35942,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -36426,6 +36815,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -36715,6 +37110,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -37026,6 +37427,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -37617,6 +38024,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -37948,6 +38361,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -38239,6 +38658,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -39145,6 +39570,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -39430,6 +39861,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -40635,6 +41072,11 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifactRepository( + configuration="configuration_example", + key_format="key_format_example", + name="name_example", + ), s3=IoArgoprojWorkflowV1alpha1S3ArtifactRepository( access_key_secret=SecretKeySelector( key="key_example", @@ -40909,6 +41351,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -41202,6 +41650,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -41505,6 +41959,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -42396,6 +42856,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -43263,6 +43729,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -43552,6 +44024,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -43863,6 +44341,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -44454,6 +44938,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -44785,6 +45275,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -45076,6 +45572,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -45982,6 +46484,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -46267,6 +46775,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -47261,6 +47775,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -47580,6 +48100,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -48265,6 +48791,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -49132,6 +49664,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -49421,6 +49959,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -49732,6 +50276,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -50323,6 +50873,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -50654,6 +51210,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -50945,6 +51507,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -51851,6 +52419,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -52136,6 +52710,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -53103,6 +53683,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -53970,6 +54556,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -54259,6 +54851,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -54570,6 +55168,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -55161,6 +55765,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -55492,6 +56102,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -55783,6 +56399,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -56689,6 +57311,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -56974,6 +57602,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), diff --git a/sdks/python/client/docs/WorkflowTemplateServiceApi.md b/sdks/python/client/docs/WorkflowTemplateServiceApi.md index a8152b56f30e..b5d2da880b5d 100644 --- a/sdks/python/client/docs/WorkflowTemplateServiceApi.md +++ b/sdks/python/client/docs/WorkflowTemplateServiceApi.md @@ -541,6 +541,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -860,6 +866,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -1545,6 +1557,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -2412,6 +2430,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -2701,6 +2725,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -3012,6 +3042,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -3603,6 +3639,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -3934,6 +3976,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -4225,6 +4273,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -5131,6 +5185,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -5416,6 +5476,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -6383,6 +6449,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -7250,6 +7322,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -7539,6 +7617,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -7850,6 +7934,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -8441,6 +8531,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -8772,6 +8868,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -9063,6 +9165,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -9969,6 +10077,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -10254,6 +10368,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -12125,6 +12245,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -12444,6 +12570,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -13129,6 +13261,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -13996,6 +14134,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -14285,6 +14429,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -14596,6 +14746,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -15187,6 +15343,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -15518,6 +15680,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -15809,6 +15977,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -16715,6 +16889,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -17000,6 +17180,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -17967,6 +18153,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -18834,6 +19026,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -19123,6 +19321,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -19434,6 +19638,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -20025,6 +20235,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -20356,6 +20572,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -20647,6 +20869,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -21553,6 +21781,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -21838,6 +22072,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -23620,6 +23860,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -23939,6 +24185,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -24624,6 +24876,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -25491,6 +25749,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -25780,6 +26044,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -26091,6 +26361,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -26682,6 +26958,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -27013,6 +27295,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -27304,6 +27592,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -28210,6 +28504,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -28495,6 +28795,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -29462,6 +29768,12 @@ with argo_workflows.ApiClient(configuration) as api_client: security_token="security_token_example", use_sdk_creds=True, ), + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -30329,6 +30641,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -30618,6 +30936,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -30929,6 +31253,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -31520,6 +31850,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -31851,6 +32187,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -32142,6 +32484,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -33048,6 +33396,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), @@ -33333,6 +33687,12 @@ with argo_workflows.ApiClient(configuration) as api_client: use_sdk_creds=True, ), path="path_example", + plugin=IoArgoprojWorkflowV1alpha1PluginArtifact( + configuration="configuration_example", + connection_timeout_seconds=1, + key="key_example", + name="name_example", + ), raw=IoArgoprojWorkflowV1alpha1RawArtifact( data="data_example", ), diff --git a/server/apiserver/argoserver.go b/server/apiserver/argoserver.go index 71c085c91847..1b457e4c0ede 100644 --- a/server/apiserver/argoserver.go +++ b/server/apiserver/argoserver.go @@ -3,11 +3,14 @@ package apiserver import ( "context" "crypto/tls" + "errors" "fmt" "net" "net/http" "os" + "slices" "strings" + "sync" "time" "github.com/gorilla/handlers" @@ -15,11 +18,15 @@ import ( grpc_prometheus "github.com/grpc-ecosystem/go-grpc-prometheus" "github.com/grpc-ecosystem/grpc-gateway/runtime" "github.com/prometheus/client_golang/prometheus/promhttp" + "github.com/sethvargo/go-limiter" + "github.com/sethvargo/go-limiter/httplimit" + "github.com/sethvargo/go-limiter/memorystore" "google.golang.org/grpc" "google.golang.org/grpc/credentials" "google.golang.org/grpc/credentials/insecure" "google.golang.org/grpc/metadata" v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/util/wait" "k8s.io/client-go/kubernetes" "k8s.io/client-go/rest" @@ -52,7 +59,7 @@ import ( "github.com/argoproj/argo-workflows/v3/server/info" "github.com/argoproj/argo-workflows/v3/server/sensor" "github.com/argoproj/argo-workflows/v3/server/static" - "github.com/argoproj/argo-workflows/v3/server/sync" + serversync "github.com/argoproj/argo-workflows/v3/server/sync" "github.com/argoproj/argo-workflows/v3/server/types" "github.com/argoproj/argo-workflows/v3/server/workflow" "github.com/argoproj/argo-workflows/v3/server/workflow/store" @@ -62,16 +69,14 @@ import ( grpcutil "github.com/argoproj/argo-workflows/v3/util/grpc" "github.com/argoproj/argo-workflows/v3/util/instanceid" "github.com/argoproj/argo-workflows/v3/util/json" + k8sutil "github.com/argoproj/argo-workflows/v3/util/k8s" "github.com/argoproj/argo-workflows/v3/util/logging" rbacutil "github.com/argoproj/argo-workflows/v3/util/rbac" "github.com/argoproj/argo-workflows/v3/util/sqldb" "github.com/argoproj/argo-workflows/v3/workflow/artifactrepositories" + "github.com/argoproj/argo-workflows/v3/workflow/artifacts/plugin" "github.com/argoproj/argo-workflows/v3/workflow/events" "github.com/argoproj/argo-workflows/v3/workflow/hydrator" - - "github.com/sethvargo/go-limiter" - "github.com/sethvargo/go-limiter/httplimit" - "github.com/sethvargo/go-limiter/memorystore" ) var MaxGRPCMessageSize int @@ -211,7 +216,19 @@ func (as *argoServer) Run(ctx context.Context, port int, browserOpenFunc func(st if err != nil { log.WithFatal().Error(ctx, err.Error()) } + + // Validate artifact driver images against server pod images + if err := as.validateArtifactDriverImages(ctx, config); err != nil { + log.WithFatal().WithError(err).Error(ctx, "failed to validate artifact driver images") + } + + // Validate artifact driver connections + if err := as.validateArtifactDriverConnections(ctx, config); err != nil { + log.WithFatal().WithError(err).Error(ctx, "failed to validate artifact driver connections") + } + log.WithFields(argo.GetVersion().Fields()).WithField("instanceID", config.InstanceID).Info(ctx, "Starting Argo Server") + instanceIDService := instanceid.NewService(config.InstanceID) offloadRepo := persist.ExplosiveOffloadNodeStatusRepo wfArchive := persist.NullWorkflowArchive @@ -255,7 +272,7 @@ func (as *argoServer) Run(ctx context.Context, port int, browserOpenFunc func(st artifactServer := artifacts.NewArtifactServer(as.gatekeeper, hydrator.New(offloadRepo), wfArchive, instanceIDService, artifactRepositories, log) eventServer := event.NewController(ctx, instanceIDService, eventRecorderManager, as.eventQueueSize, as.eventWorkerCount, as.eventAsyncDispatch) wfArchiveServer := workflowarchive.NewWorkflowArchiveServer(wfArchive, offloadRepo, config.WorkflowDefaults) - syncServer := sync.NewSyncServer() + syncServer := serversync.NewSyncServer() wfStore, err := store.NewSQLiteStore(instanceIDService) if err != nil { log.WithFatal().Error(ctx, err.Error()) @@ -448,6 +465,111 @@ func (as *argoServer) newHTTPServer(ctx context.Context, port int, artifactServe return handler } +// validateArtifactDriverConnections validates that all configured artifact drivers can be connected to +func (as *argoServer) validateArtifactDriverConnections(ctx context.Context, cfg *config.Config) error { + log := logging.RequireLoggerFromContext(ctx) + if len(cfg.ArtifactDrivers) == 0 { + log.Info(ctx, "No artifact drivers configured, skipping connection validation") + return nil + } + + log.Info(ctx, "Validating artifact driver connections") + + var wg sync.WaitGroup + errorChannel := make(chan error, len(cfg.ArtifactDrivers)) + + // Validate each driver connection in parallel + for _, driver := range cfg.ArtifactDrivers { + wg.Add(1) + go func(driver config.ArtifactDriver) { + defer wg.Done() + + // Create a new driver connection + pluginDriver, err := plugin.NewDriver(ctx, driver.Name, driver.Name.SocketPath(), 5) // replace with driver.ConnectionTimeoutSeconds once we have it + if err != nil { + errorChannel <- fmt.Errorf("failed to connect to artifact driver %s: %w", driver.Name, err) + return + } + + // Close the connection after validation + defer func() { + if closeErr := pluginDriver.Close(); closeErr != nil { + log.WithError(closeErr).WithField("driver", driver.Name).Warn(ctx, "Failed to close connection to artifact driver") + } + }() + + log.WithField("driver", driver.Name).Info(ctx, "Successfully validated connection to artifact driver") + }(driver) + } + + // Wait for all validations to complete + wg.Wait() + close(errorChannel) + + // Collect any errors + var connectionErrors []string + for err := range errorChannel { + connectionErrors = append(connectionErrors, err.Error()) + } + + if len(connectionErrors) > 0 { + errorMsg := fmt.Sprintf("Artifact driver connection validation failed: %v", connectionErrors) + log.WithField("errors", connectionErrors).Error(ctx, errorMsg) + return errors.New(errorMsg) + } + + log.WithField("driverCount", len(cfg.ArtifactDrivers)).Info(ctx, "Artifact driver connection validation passed: All configured artifact drivers are accessible") + return nil +} + +// validateArtifactDriverImages validates that the artifact driver images are present in the server pod +func (as *argoServer) validateArtifactDriverImages(ctx context.Context, cfg *config.Config) error { + log := logging.RequireLoggerFromContext(ctx) + if len(cfg.ArtifactDrivers) == 0 { + log.Info(ctx, "No artifact drivers configured, skipping validation") + return nil + } + + log.Info(ctx, "Validating artifact driver images against server pod") + + // Get the current pod name using the standard Argo pattern + podName, err := k8sutil.GetCurrentPodName(ctx, as.clients.Kubernetes, as.namespace, "app=argo-server") + if err != nil { + log.WithError(err).Warn(ctx, "Failed to get current pod name, cannot validate artifact driver images") + return nil + } + + log.WithField("podName", podName).Debug(ctx, "Found argo-server pod for validation") + + // Get the current pod to check the available images + pod, err := as.clients.Kubernetes.CoreV1().Pods(as.namespace).Get(ctx, podName, metav1.GetOptions{}) + if err != nil { + log.WithError(err).WithField("podName", podName).Warn(ctx, "Failed to get current pod, cannot validate artifact driver images") + return nil + } + + // Get missing images + images := make([]string, 0, len(cfg.ArtifactDrivers)) + for _, driver := range cfg.ArtifactDrivers { + images = append(images, driver.Image) + } + + for _, container := range pod.Spec.Containers { + images = slices.DeleteFunc(images, func(image string) bool { + return image == container.Image + }) + } + + if len(images) > 0 { + errorMsg := fmt.Sprintf("Artifact driver validation failed: The following artifact driver images are not present in the server pod: %v. Please ensure all artifact driver images are included in the argo-server pod.", images) + log.Error(ctx, errorMsg) + return errors.New(errorMsg) + } + + log.WithField("driverCount", len(cfg.ArtifactDrivers)).Info(ctx, "Artifact driver validation passed: All configured artifact driver images are present in the server pod") + return nil +} + type registerFunc func(ctx context.Context, mux *runtime.ServeMux, endpoint string, opts []grpc.DialOption) error // mustRegisterGWHandler is a convenience function to register a gateway handler diff --git a/server/apiserver/argoserver_test.go b/server/apiserver/argoserver_test.go new file mode 100644 index 000000000000..3a57c63ffa01 --- /dev/null +++ b/server/apiserver/argoserver_test.go @@ -0,0 +1,233 @@ +package apiserver + +import ( + "testing" + + "github.com/stretchr/testify/require" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/fake" + + "github.com/argoproj/argo-workflows/v3/config" + "github.com/argoproj/argo-workflows/v3/server/types" + "github.com/argoproj/argo-workflows/v3/util/logging" + "github.com/argoproj/argo-workflows/v3/workflow/common" +) + +func TestValidateArtifactDriverImages(t *testing.T) { + tests := []struct { + name string + config *config.Config + pod *corev1.Pod + expectedError bool + expectedErrMsg string + }{ + { + name: "No artifact drivers configured - should skip validation", + config: &config.Config{ + ArtifactDrivers: []config.ArtifactDriver{}, + }, + expectedError: false, + }, + { + name: "All artifact driver images present in pod - should pass", + config: &config.Config{ + ArtifactDrivers: []config.ArtifactDriver{ + { + Name: "my-driver", + Image: "my-driver:latest", + }, + { + Name: "another-driver", + Image: "another-driver:v1.0", + }, + }, + }, + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod", + Namespace: "argo", + Labels: map[string]string{ + "app": "argo-server", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "argo-server", + Image: "quay.io/argoproj/argocli:latest", + }, + { + Name: "my-driver", + Image: "my-driver:latest", + }, + { + Name: "another-driver", + Image: "another-driver:v1.0", + }, + }, + }, + Status: corev1.PodStatus{ + Phase: corev1.PodRunning, + }, + }, + expectedError: false, + }, + { + name: "Missing artifact driver image in pod - should fail", + config: &config.Config{ + ArtifactDrivers: []config.ArtifactDriver{ + { + Name: "my-driver", + Image: "my-driver:latest", + }, + { + Name: "missing-driver", + Image: "missing-driver:v1.0", + }, + }, + }, + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod", + Namespace: "argo", + Labels: map[string]string{ + "app": "argo-server", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "argo-server", + Image: "quay.io/argoproj/argocli:latest", + }, + { + Name: "my-driver", + Image: "my-driver:latest", + }, + }, + }, + Status: corev1.PodStatus{ + Phase: corev1.PodRunning, + }, + }, + expectedError: true, + expectedErrMsg: "Artifact driver validation failed: The following artifact driver images are not present in the server pod: [missing-driver:v1.0]", + }, + { + name: "Artifact driver image in regular container - should pass", + config: &config.Config{ + ArtifactDrivers: []config.ArtifactDriver{ + { + Name: "sidecar-driver", + Image: "sidecar-driver:latest", + }, + }, + }, + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod", + Namespace: "argo", + Labels: map[string]string{ + "app": "argo-server", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "argo-server", + Image: "quay.io/argoproj/argocli:latest", + }, + { + Name: "sidecar-driver", + Image: "sidecar-driver:latest", + }, + }, + }, + Status: corev1.PodStatus{ + Phase: corev1.PodRunning, + }, + }, + expectedError: false, + }, + { + name: "Test fallback to label selector when ARGO_POD_NAME not set", + config: &config.Config{ + ArtifactDrivers: []config.ArtifactDriver{ + { + Name: "fallback-driver", + Image: "fallback-driver:latest", + }, + }, + }, + pod: &corev1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "fallback-test-pod", + Namespace: "argo", + Labels: map[string]string{ + "app": "argo-server", + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{ + { + Name: "argo-server", + Image: "quay.io/argoproj/argocli:latest", + }, + { + Name: "fallback-driver", + Image: "fallback-driver:latest", + }, + }, + }, + Status: corev1.PodStatus{ + Phase: corev1.PodRunning, + }, + }, + expectedError: false, + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + // Create fake Kubernetes client + fakeClient := fake.NewSimpleClientset() + + // Create the argoServer instance + as := &argoServer{ + clients: &types.Clients{ + Kubernetes: fakeClient, + }, + namespace: "argo", + } + + // Set up the test data + ctx := logging.TestContext(t.Context()) + if tt.pod != nil { + _, err := fakeClient.CoreV1().Pods("argo").Create(ctx, tt.pod, metav1.CreateOptions{}) + require.NoError(t, err) + } + + // Set ARGO_POD_NAME environment variable for most tests, except the fallback test + if tt.name != "Test fallback to label selector when ARGO_POD_NAME not set" { + t.Setenv(common.EnvVarPodName, "test-pod") + } else { + // For the fallback test, ensure the environment variable is not set + t.Setenv(common.EnvVarPodName, "") + } + + // Run the validation with proper logging context + err := as.validateArtifactDriverImages(ctx, tt.config) + + // Check results + if tt.expectedError { + require.Error(t, err) + if tt.expectedErrMsg != "" { + require.Contains(t, err.Error(), tt.expectedErrMsg) + } + } else { + require.NoError(t, err) + } + }) + } +} diff --git a/server/artifacts/artifact_server.go b/server/artifacts/artifact_server.go index cf0d5f483959..163a601a0ba8 100644 --- a/server/artifacts/artifact_server.go +++ b/server/artifacts/artifact_server.go @@ -25,7 +25,7 @@ import ( "github.com/argoproj/argo-workflows/v3/util/instanceid" "github.com/argoproj/argo-workflows/v3/util/logging" "github.com/argoproj/argo-workflows/v3/workflow/artifactrepositories" - artifact "github.com/argoproj/argo-workflows/v3/workflow/artifacts" + "github.com/argoproj/argo-workflows/v3/workflow/artifacts" "github.com/argoproj/argo-workflows/v3/workflow/artifacts/common" "github.com/argoproj/argo-workflows/v3/workflow/hydrator" "github.com/argoproj/argo-workflows/v3/workflow/util" @@ -36,7 +36,7 @@ type ArtifactServer struct { hydrator hydrator.Interface wfArchive sqldb.WorkflowArchive instanceIDService instanceid.Service - artDriverFactory artifact.NewDriverFunc + artDriverFactory artifacts.NewDriverFunc artifactRepositories artifactrepositories.Interface logger logging.Logger } @@ -49,10 +49,10 @@ const ( ) func NewArtifactServer(authN auth.Gatekeeper, hydrator hydrator.Interface, wfArchive sqldb.WorkflowArchive, instanceIDService instanceid.Service, artifactRepositories artifactrepositories.Interface, logger logging.Logger) *ArtifactServer { - return newArtifactServer(authN, hydrator, wfArchive, instanceIDService, artifact.NewDriver, artifactRepositories, logger) + return newArtifactServer(authN, hydrator, wfArchive, instanceIDService, artifacts.NewDriver, artifactRepositories, logger) } -func newArtifactServer(authN auth.Gatekeeper, hydrator hydrator.Interface, wfArchive sqldb.WorkflowArchive, instanceIDService instanceid.Service, artDriverFactory artifact.NewDriverFunc, artifactRepositories artifactrepositories.Interface, logger logging.Logger) *ArtifactServer { +func newArtifactServer(authN auth.Gatekeeper, hydrator hydrator.Interface, wfArchive sqldb.WorkflowArchive, instanceIDService instanceid.Service, artDriverFactory artifacts.NewDriverFunc, artifactRepositories artifactrepositories.Interface, logger logging.Logger) *ArtifactServer { return &ArtifactServer{authN, hydrator, wfArchive, instanceIDService, artDriverFactory, artifactRepositories, logger} } diff --git a/test/e2e/artifacts_test.go b/test/e2e/artifacts_test.go index 4792ba22bcf1..9a7d3f46c4e5 100644 --- a/test/e2e/artifacts_test.go +++ b/test/e2e/artifacts_test.go @@ -4,7 +4,10 @@ package e2e import ( "bytes" + "compress/gzip" "fmt" + "io" + "strings" "testing" "time" @@ -46,6 +49,57 @@ func (s *ArtifactsSuite) TestOutputOnMount() { WaitForWorkflow(fixtures.ToBeSucceeded) } +func (s *ArtifactsSuite) TestOutputOnMountPlugin() { + s.Given(). + Workflow("@testdata/output-on-mount-plugin-workflow.yaml"). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded). + Then(). + ExpectArtifact("-", "out-0", "plugin-bucket", func(t *testing.T, object minio.ObjectInfo, err error) { + require.NoError(t, err) + // Verify the artifact content contains the expected output + s.checkArtifactContent(t, "plugin-bucket", object.Key, "hi") + }) +} + +func (s *ArtifactsSuite) TestInputOnMountPlugin() { + s.Given(). + Workflow("@testdata/input-on-mount-plugin-workflow.yaml"). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded). + Then(). + ExpectWorkflowNode(func(status wfv1.NodeStatus) bool { + return strings.Contains(status.Name, "create-artifact") && status.TemplateName == "create" + }, func(t *testing.T, n *wfv1.NodeStatus, pod *corev1.Pod) { + assert.Equal(t, wfv1.NodeSucceeded, n.Phase) + artifact := n.Outputs.GetArtifactByName("artifact") + require.NotNil(t, artifact, "artifact should exist") + key, err := artifact.GetKey() + require.NoError(t, err) + s.checkArtifactContent(t, "plugin-bucket", key, "hello plugin mount") + }). + ExpectWorkflowNode(wfv1.NodeWithDisplayName("read-artifact"), + func(t *testing.T, n *wfv1.NodeStatus, pod *corev1.Pod) { + assert.Equal(t, wfv1.NodeSucceeded, n.Phase) + }) +} + +func (s *ArtifactsSuite) TestOutputOnInputPlugin() { + s.Given(). + Workflow("@testdata/output-on-input-plugin-workflow.yaml"). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded). + Then(). + ExpectArtifact("-", "out-0", "plugin-bucket", func(t *testing.T, object minio.ObjectInfo, err error) { + require.NoError(t, err) + // Verify the artifact content contains the expected output + s.checkArtifactContent(t, "plugin-bucket", object.Key, "hi") + }) +} + func (s *ArtifactsSuite) TestOutputOnInput() { s.Given(). Workflow("@testdata/output-on-input-workflow.yaml"). @@ -62,6 +116,14 @@ func (s *ArtifactsSuite) TestArtifactPassing() { WaitForWorkflow(fixtures.ToBeSucceeded) } +func (s *ArtifactsSuite) TestArtifactPassingPlugin() { + s.Given(). + Workflow("@testdata/artifact-passing-plugin-workflow.yaml"). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded) +} + type expectedArtifact struct { key string bucketName string @@ -89,6 +151,22 @@ func (s *ArtifactsSuite) TestGlobalArtifactPassing() { value: "Updated testUpdate", }, }, + { + workflowFile: "@testdata/global-artifact-passing-plugin.yaml", + expectedArtifact: expectedArtifact{ + key: "globalArtifactPlugin", + bucketName: "my-bucket-3", + value: "01", + }, + }, + { + workflowFile: "@testdata/complex-global-artifact-passing-plugin.yaml", + expectedArtifact: expectedArtifact{ + key: "finalTestUpdatePlugin", + bucketName: "my-bucket-3", + value: "Updated testUpdate", + }, + }, } { then := s.Given(). Workflow(tt.workflowFile). @@ -164,10 +242,14 @@ func (al *s3Location) getS3Key(wf *wfv1.Workflow) (string, error) { } for _, a := range n.Outputs.Artifacts { if a.Name == al.derivedKey.artifactName { - if a.S3 == nil { - return "", fmt.Errorf("didn't find expected S3 field in artifact %q: %+v", al.derivedKey.artifactName, a) + // Support both S3 and Plugin artifacts + if a.S3 != nil { + return a.S3.Key, nil + } + if a.Plugin != nil { + return a.Plugin.Key, nil } - return a.S3.Key, nil + return "", fmt.Errorf("artifact %q has neither S3 nor Plugin field: %+v", al.derivedKey.artifactName, a) } } @@ -285,6 +367,26 @@ func (s *ArtifactsSuite) TestDeleteWorkflow() { when.RemoveFinalizers(false) } +func (s *ArtifactsSuite) TestDeleteWorkflowPlugin() { + when := s.Given(). + Workflow("@testdata/artifactgc/artgc-dag-wf-self-delete-plugin.yaml"). + When(). + SubmitWorkflow() + + then := when. + WaitForWorkflow(fixtures.ToBeCompleted). + Then(). + ExpectWorkflow(func(t *testing.T, objectMeta *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + assert.Contains(t, objectMeta.Finalizers, common.FinalizerArtifactGC) + }) + + when = then.When() + + when.WaitForWorkflowDeletion() + + when.RemoveFinalizers(false) +} + func (s *ArtifactsSuite) TestArtifactGC() { s.Given(). @@ -292,10 +394,15 @@ func (s *ArtifactsSuite) TestArtifactGC() { WorkflowTemplate("@testdata/artifactgc/artgc-template-2.yaml"). WorkflowTemplate("@testdata/artifactgc/artgc-template-ref-template.yaml"). WorkflowTemplate("@testdata/artifactgc/artgc-template-no-gc.yaml"). + WorkflowTemplate("@testdata/artifactgc/artgc-template-plugin.yaml"). + WorkflowTemplate("@testdata/artifactgc/artgc-template-2-plugin.yaml"). + WorkflowTemplate("@testdata/artifactgc/artgc-template-ref-template-plugin.yaml"). + WorkflowTemplate("@testdata/artifactgc/artgc-template-no-gc-plugin.yaml"). When(). CreateWorkflowTemplates() for _, tt := range []struct { + name string workflowFile string hasGC bool workflowShouldSucceed bool @@ -303,6 +410,7 @@ func (s *ArtifactsSuite) TestArtifactGC() { expectedGCPodsOnWFCompletion int }{ { + name: "MultiStrategyMultiAnnotation", workflowFile: "@testdata/artifactgc/artgc-multi-strategy-multi-anno.yaml", hasGC: true, workflowShouldSucceed: true, @@ -315,8 +423,23 @@ func (s *ArtifactsSuite) TestArtifactGC() { {s3Location{bucketName: "my-bucket-2", specifiedKey: "second-on-completion"}, true, false}, }, }, + { + name: "MultiStrategyMultiAnnotationPlugin", + workflowFile: "@testdata/artifactgc/artgc-multi-strategy-multi-anno-plugin.yaml", + hasGC: true, + workflowShouldSucceed: true, + expectedGCPodsOnWFCompletion: 2, + expectedArtifacts: []artifactState{ + {s3Location{bucketName: "plugin-bucket", specifiedKey: "first-on-completion-1"}, true, false}, + {s3Location{bucketName: "plugin-bucket", specifiedKey: "first-on-completion-2"}, true, false}, + {s3Location{bucketName: "plugin-bucket", specifiedKey: "first-no-deletion"}, false, false}, + {s3Location{bucketName: "plugin-bucket", specifiedKey: "second-on-deletion"}, false, true}, + {s3Location{bucketName: "plugin-bucket", specifiedKey: "second-on-completion"}, true, false}, + }, + }, // entire Workflow based on a WorkflowTemplate { + name: "FromTemplate", workflowFile: "@testdata/artifactgc/artgc-from-template.yaml", hasGC: true, workflowShouldSucceed: true, @@ -326,8 +449,21 @@ func (s *ArtifactsSuite) TestArtifactGC() { {s3Location{bucketName: "my-bucket-2", specifiedKey: "on-deletion"}, false, true}, }, }, + // entire Workflow based on a WorkflowTemplate with a plugin + { + name: "FromTemplatePlugin", + workflowFile: "@testdata/artifactgc/artgc-from-template-plugin.yaml", + hasGC: true, + workflowShouldSucceed: true, + expectedGCPodsOnWFCompletion: 1, + expectedArtifacts: []artifactState{ + {s3Location{bucketName: "plugin-bucket", specifiedKey: "on-completion"}, true, false}, + {s3Location{bucketName: "plugin-bucket", specifiedKey: "on-deletion"}, false, true}, + }, + }, // entire Workflow based on a WorkflowTemplate { + name: "FromTemplate2", workflowFile: "@testdata/artifactgc/artgc-from-template-2.yaml", hasGC: true, workflowShouldSucceed: true, @@ -337,8 +473,20 @@ func (s *ArtifactsSuite) TestArtifactGC() { {s3Location{bucketName: "my-bucket-2", specifiedKey: "on-deletion"}, false, true}, }, }, + { + name: "FromTemplate2Plugin", + workflowFile: "@testdata/artifactgc/artgc-from-template-2-plugin.yaml", + hasGC: true, + workflowShouldSucceed: true, + expectedGCPodsOnWFCompletion: 1, + expectedArtifacts: []artifactState{ + {s3Location{bucketName: "plugin-bucket", specifiedKey: "on-completion"}, true, false}, + {s3Location{bucketName: "plugin-bucket", specifiedKey: "on-deletion"}, false, true}, + }, + }, // Step in Workflow references a WorkflowTemplate's template { + name: "StepWorkflowTemplate", workflowFile: "@testdata/artifactgc/artgc-step-wf-tmpl.yaml", hasGC: true, workflowShouldSucceed: true, @@ -348,8 +496,20 @@ func (s *ArtifactsSuite) TestArtifactGC() { {s3Location{bucketName: "my-bucket-2", specifiedKey: "on-deletion"}, false, true}, }, }, + { + name: "StepWorkflowTemplatePlugin", + workflowFile: "@testdata/artifactgc/artgc-step-wf-tmpl-plugin.yaml", + hasGC: true, + workflowShouldSucceed: true, + expectedGCPodsOnWFCompletion: 1, + expectedArtifacts: []artifactState{ + {s3Location{bucketName: "plugin-bucket", specifiedKey: "on-completion"}, true, false}, + {s3Location{bucketName: "plugin-bucket", specifiedKey: "on-deletion"}, false, true}, + }, + }, // Step in Workflow references a WorkflowTemplate's template { + name: "StepWorkflowTemplate2", workflowFile: "@testdata/artifactgc/artgc-step-wf-tmpl-2.yaml", hasGC: true, workflowShouldSucceed: true, @@ -359,8 +519,20 @@ func (s *ArtifactsSuite) TestArtifactGC() { {s3Location{bucketName: "my-bucket-2", specifiedKey: "on-deletion"}, false, false}, }, }, + { + name: "StepWorkflowTemplate2Plugin", + workflowFile: "@testdata/artifactgc/artgc-step-wf-tmpl-2-plugin.yaml", + hasGC: true, + workflowShouldSucceed: true, + expectedGCPodsOnWFCompletion: 1, + expectedArtifacts: []artifactState{ + {s3Location{bucketName: "plugin-bucket", specifiedKey: "on-completion"}, true, false}, + {s3Location{bucketName: "plugin-bucket", specifiedKey: "on-deletion"}, false, false}, + }, + }, // entire Workflow based on a WorkflowTemplate which has a Step that references another WorkflowTemplate's template { + name: "FromRefTemplate", workflowFile: "@testdata/artifactgc/artgc-from-ref-template.yaml", hasGC: true, workflowShouldSucceed: true, @@ -370,17 +542,38 @@ func (s *ArtifactsSuite) TestArtifactGC() { {s3Location{bucketName: "my-bucket-2", specifiedKey: "on-deletion"}, false, true}, }, }, + { + name: "FromRefTemplatePlugin", + workflowFile: "@testdata/artifactgc/artgc-from-ref-template-plugin.yaml", + hasGC: true, + workflowShouldSucceed: true, + expectedGCPodsOnWFCompletion: 1, + expectedArtifacts: []artifactState{ + {s3Location{bucketName: "plugin-bucket", specifiedKey: "on-completion"}, true, false}, + {s3Location{bucketName: "plugin-bucket", specifiedKey: "on-deletion"}, false, true}, + }, + }, // Step in Workflow references a WorkflowTemplate's template // Workflow defines ArtifactGC but all artifacts override with "Never" so Artifact GC should not be done { + name: "StepWorkflowTemplateNoGC", workflowFile: "@testdata/artifactgc/artgc-step-wf-tmpl-no-gc.yaml", hasGC: false, workflowShouldSucceed: true, expectedGCPodsOnWFCompletion: 0, expectedArtifacts: []artifactState{}, }, + { + name: "StepWorkflowTemplateNoGCPlugin", + workflowFile: "@testdata/artifactgc/artgc-step-wf-tmpl-no-gc-plugin.yaml", + hasGC: false, + workflowShouldSucceed: true, + expectedGCPodsOnWFCompletion: 0, + expectedArtifacts: []artifactState{}, + }, // Workflow fails to write an artifact that's been defined as an Output { + name: "NonOptionalArtifactNotWritten", workflowFile: "@testdata/artifactgc/artgc-non-optional-artifact-not-written.yaml", hasGC: true, workflowShouldSucceed: false, // artifact not being present causes Workflow to fail @@ -390,8 +583,20 @@ func (s *ArtifactsSuite) TestArtifactGC() { {s3Location{bucketName: "my-bucket", derivedKey: &artifactDerivedKey{templateName: "some-artifacts-not-written", artifactName: "present"}}, false, true}, }, }, + { + name: "NonOptionalArtifactNotWrittenPlugin", + workflowFile: "@testdata/artifactgc/artgc-non-optional-artifact-not-written-plugin.yaml", + hasGC: true, + workflowShouldSucceed: false, + expectedGCPodsOnWFCompletion: 0, + expectedArtifacts: []artifactState{ + {s3Location{bucketName: "plugin-bucket", derivedKey: &artifactDerivedKey{templateName: "artifact-written", artifactName: "present"}}, false, true}, + {s3Location{bucketName: "plugin-bucket", derivedKey: &artifactDerivedKey{templateName: "some-artifacts-not-written", artifactName: "present"}}, false, true}, + }, + }, // Workflow doesn't write an artifact that's been defined as an Output, but it's an Optional artifact, so Workflow succeeds { + name: "OptionalArtifactNotWritten", workflowFile: "@testdata/artifactgc/artgc-optional-artifact-not-written.yaml", hasGC: true, workflowShouldSucceed: true, @@ -401,109 +606,131 @@ func (s *ArtifactsSuite) TestArtifactGC() { {s3Location{bucketName: "my-bucket", derivedKey: &artifactDerivedKey{templateName: "some-artifacts-not-written", artifactName: "present"}}, false, true}, }, }, + { + name: "OptionalArtifactNotWrittenPlugin", + workflowFile: "@testdata/artifactgc/artgc-optional-artifact-not-written-plugin.yaml", + hasGC: true, + workflowShouldSucceed: true, + expectedGCPodsOnWFCompletion: 0, + expectedArtifacts: []artifactState{ + {s3Location{bucketName: "plugin-bucket", derivedKey: &artifactDerivedKey{templateName: "artifact-written", artifactName: "present"}}, false, true}, + {s3Location{bucketName: "plugin-bucket", derivedKey: &artifactDerivedKey{templateName: "some-artifacts-not-written", artifactName: "present"}}, false, true}, + }, + }, // Workflow defined output artifact but execution failed, no artifacts to be gced { + name: "ArtifactNotWrittenFailed", workflowFile: "@testdata/artifactgc/artgc-artifact-not-written-failed.yaml", hasGC: true, workflowShouldSucceed: false, expectedGCPodsOnWFCompletion: 0, expectedArtifacts: []artifactState{}, }, + { + name: "ArtifactNotWrittenFailedPlugin", + workflowFile: "@testdata/artifactgc/artgc-artifact-not-written-failed-plugin.yaml", + hasGC: true, + workflowShouldSucceed: false, + expectedGCPodsOnWFCompletion: 0, + expectedArtifacts: []artifactState{}, + }, } { - // for each test make sure that: - // 1. the finalizer gets added - // 2. the artifacts are deleted at the right time - // 3. the finalizer gets removed after all artifacts are deleted - // (note that in order to verify that the finalizer has been added once the Workflow's been submitted, - // we need it to still be there after being submitted, so each of the following tests includes at least one - // 'OnWorkflowDeletion' strategy) - - when := s.Given(). - Workflow(tt.workflowFile). - When(). - SubmitWorkflow() - when. - WaitForWorkflow(fixtures.ToBeCompleted). - Then(). - ExpectWorkflow(func(t *testing.T, objectMeta *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { - if tt.hasGC { - assert.Contains(t, objectMeta.Finalizers, common.FinalizerArtifactGC) - } - }) - - if tt.workflowShouldSucceed && when.WorkflowCondition(func(wf *wfv1.Workflow) bool { - return wf.Status.Phase == wfv1.WorkflowFailed || wf.Status.Phase == wfv1.WorkflowError - }) { - fmt.Println("can't reliably verify Artifact GC since workflow failed") - when.RemoveFinalizers(false) - continue - } - - // wait for all pods to have started and been completed and recouped - when. - WaitForWorkflow( - fixtures.WorkflowCompletionOkay(true), - fixtures.Condition(func(wf *wfv1.Workflow) (bool, string) { - return (len(wf.Status.ArtifactGCStatus.PodsRecouped) >= tt.expectedGCPodsOnWFCompletion) || (tt.expectedGCPodsOnWFCompletion == 0), - fmt.Sprintf("for all %d pods to have been recouped", tt.expectedGCPodsOnWFCompletion) - })) - - then := when.Then() + s.Run(tt.name, func() { + // for each test make sure that: + // 1. the finalizer gets added + // 2. the artifacts are deleted at the right time + // 3. the finalizer gets removed after all artifacts are deleted + // (note that in order to verify that the finalizer has been added once the Workflow's been submitted, + // we need it to still be there after being submitted, so each of the following tests includes at least one + // 'OnWorkflowDeletion' strategy) + + when := s.Given(). + Workflow(tt.workflowFile). + When(). + SubmitWorkflow() + when. + WaitForWorkflow(fixtures.ToBeCompleted). + Then(). + ExpectWorkflow(func(t *testing.T, objectMeta *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + if tt.hasGC { + assert.Contains(t, objectMeta.Finalizers, common.FinalizerArtifactGC) + } + }) - // verify that the artifacts that should have been deleted at completion time were - for _, expectedArtifact := range tt.expectedArtifacts { - artifactKey, err := expectedArtifact.artifactLocation.getS3Key(when.GetWorkflow()) - fmt.Printf("artifact key: %q\n", artifactKey) - if err != nil { - panic(err) + if tt.workflowShouldSucceed && when.WorkflowCondition(func(wf *wfv1.Workflow) bool { + return wf.Status.Phase == wfv1.WorkflowFailed || wf.Status.Phase == wfv1.WorkflowError + }) { + fmt.Println("can't reliably verify Artifact GC since workflow failed") + when.RemoveFinalizers(false) + return } - if expectedArtifact.deletedAtWFCompletion { - fmt.Printf("verifying artifact %s is deleted at completion time\n", artifactKey) - then.ExpectArtifactByKey(artifactKey, expectedArtifact.artifactLocation.bucketName, func(t *testing.T, object minio.ObjectInfo, err error) { - require.Error(t, err) - }) - } else { - fmt.Printf("verifying artifact %s is not deleted at completion time\n", artifactKey) - then.ExpectArtifactByKey(artifactKey, expectedArtifact.artifactLocation.bucketName, func(t *testing.T, object minio.ObjectInfo, err error) { - require.NoError(t, err) - }) + + // wait for all pods to have started and been completed and recouped + when. + WaitForWorkflow( + fixtures.WorkflowCompletionOkay(true), + fixtures.Condition(func(wf *wfv1.Workflow) (bool, string) { + return (len(wf.Status.ArtifactGCStatus.PodsRecouped) >= tt.expectedGCPodsOnWFCompletion) || (tt.expectedGCPodsOnWFCompletion == 0), + fmt.Sprintf("for all %d pods to have been recouped", tt.expectedGCPodsOnWFCompletion) + })) + + then := when.Then() + + // verify that the artifacts that should have been deleted at completion time were + for _, expectedArtifact := range tt.expectedArtifacts { + artifactKey, err := expectedArtifact.artifactLocation.getS3Key(when.GetWorkflow()) + fmt.Printf("artifact key: %q\n", artifactKey) + if err != nil { + panic(err) + } + if expectedArtifact.deletedAtWFCompletion { + fmt.Printf("verifying artifact %s is deleted at completion time\n", artifactKey) + then.ExpectArtifactByKey(artifactKey, expectedArtifact.artifactLocation.bucketName, func(t *testing.T, object minio.ObjectInfo, err error) { + require.Error(t, err) + }) + } else { + fmt.Printf("verifying artifact %s is not deleted at completion time\n", artifactKey) + then.ExpectArtifactByKey(artifactKey, expectedArtifact.artifactLocation.bucketName, func(t *testing.T, object minio.ObjectInfo, err error) { + require.NoError(t, err) + }) + } } - } - fmt.Println("deleting workflow; verifying that Artifact GC finalizer gets removed") + fmt.Println("deleting workflow; verifying that Artifact GC finalizer gets removed") - when. - DeleteWorkflow(). - WaitForWorkflowDeletion(). - Then(). - ExpectWorkflowDeleted() + when. + DeleteWorkflow(). + WaitForWorkflowDeletion(). + Then(). + ExpectWorkflowDeleted() - when = when.RemoveFinalizers(false) // just in case - if the above test failed we need to forcibly remove the finalizer for Artifact GC + when = when.RemoveFinalizers(false) // just in case - if the above test failed we need to forcibly remove the finalizer for Artifact GC - then = when.Then() + then = when.Then() - for _, expectedArtifact := range tt.expectedArtifacts { - artifactKey, err := expectedArtifact.artifactLocation.getS3Key(when.GetWorkflow()) - fmt.Printf("artifact key: %q\n", artifactKey) - if err != nil { - panic(err) - } + for _, expectedArtifact := range tt.expectedArtifacts { + artifactKey, err := expectedArtifact.artifactLocation.getS3Key(when.GetWorkflow()) + fmt.Printf("artifact key: %q\n", artifactKey) + if err != nil { + panic(err) + } - if expectedArtifact.deletedAtWFCompletion { // already checked this - continue - } - if expectedArtifact.deletedAtWFDeletion { - fmt.Printf("verifying artifact %s is deleted\n", artifactKey) - then.ExpectArtifactByKey(artifactKey, expectedArtifact.artifactLocation.bucketName, func(t *testing.T, object minio.ObjectInfo, err error) { - require.Error(t, err) - }) - } else { - fmt.Printf("verifying artifact %s is not deleted\n", artifactKey) - then.ExpectArtifactByKey(artifactKey, expectedArtifact.artifactLocation.bucketName, func(t *testing.T, object minio.ObjectInfo, err error) { - require.NoError(t, err) - }) + if expectedArtifact.deletedAtWFCompletion { // already checked this + continue + } + if expectedArtifact.deletedAtWFDeletion { + fmt.Printf("verifying artifact %s is deleted\n", artifactKey) + then.ExpectArtifactByKey(artifactKey, expectedArtifact.artifactLocation.bucketName, func(t *testing.T, object minio.ObjectInfo, err error) { + require.Error(t, err) + }) + } else { + fmt.Printf("verifying artifact %s is not deleted\n", artifactKey) + then.ExpectArtifactByKey(artifactKey, expectedArtifact.artifactLocation.bucketName, func(t *testing.T, object minio.ObjectInfo, err error) { + require.NoError(t, err) + }) + } } - } + }) } } @@ -671,6 +898,27 @@ spec: }) } +func (s *ArtifactsSuite) TestDefaultParameterOutputsPlugin() { + s.Given(). + Workflow("@testdata/default-params-plugin-workflow.yaml"). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded). + Then(). + ExpectWorkflow(func(t *testing.T, _ *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + assert.True(t, status.Nodes.Any(func(node wfv1.NodeStatus) bool { + if node.Outputs != nil { + for _, param := range node.Outputs.Parameters { + if param.Value != nil && param.Value.String() == "Default value" { + return true + } + } + } + return false + })) + }) +} + func (s *ArtifactsSuite) TestSameInputOutputPathOptionalArtifact() { s.Given(). Workflow("@testdata/same-input-output-path-optional.yaml"). @@ -679,6 +927,14 @@ func (s *ArtifactsSuite) TestSameInputOutputPathOptionalArtifact() { WaitForWorkflow(fixtures.ToBeSucceeded) } +func (s *ArtifactsSuite) TestSameInputOutputPathOptionalArtifactPlugin() { + s.Given(). + Workflow("@testdata/same-input-output-path-optional-plugin.yaml"). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded) +} + func (s *ArtifactsSuite) TestOutputResult() { s.Given(). Workflow("@testdata/output-result-workflow.yaml"). @@ -704,6 +960,7 @@ func (s *ArtifactsSuite) TestMainLog() { Then(). ExpectArtifact("-", "main-logs", "my-bucket", func(t *testing.T, object minio.ObjectInfo, err error) { require.NoError(t, err) + s.checkArtifactContent(t, "my-bucket", object.Key, ":) Hello Argo!") }) }) s.Run("ActiveDeadlineSeconds", func() { @@ -715,6 +972,36 @@ func (s *ArtifactsSuite) TestMainLog() { Then(). ExpectArtifact("-", "main-logs", "my-bucket", func(t *testing.T, object minio.ObjectInfo, err error) { require.NoError(t, err) + s.checkArtifactContent(t, "my-bucket", object.Key, "123") + }) + }) +} + +func (s *ArtifactsSuite) TestMainLogPlugin() { + s.Run("Basic", func() { + s.Given(). + Workflow("@testdata/main-log-plugin-workflow.yaml"). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded). + Then(). + ExpectArtifact("-", "main-logs", "plugin-bucket", func(t *testing.T, object minio.ObjectInfo, err error) { + require.NoError(t, err) + // Verify the log content contains our expected message + s.checkArtifactContent(t, "plugin-bucket", object.Key, ":) Hello Argo Plugin Logs!") + }) + }) + s.Run("ActiveDeadlineSeconds", func() { + s.Given(). + Workflow("@expectedfailures/timeouts-step-plugin.yaml"). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeFailed). + Then(). + ExpectArtifact("-", "main-logs", "plugin-bucket", func(t *testing.T, object minio.ObjectInfo, err error) { + require.NoError(t, err) + // Verify the log content contains the echo output from the timeout test + s.checkArtifactContent(t, "plugin-bucket", object.Key, "123") }) }) } @@ -761,6 +1048,55 @@ spec: }) } +func (s *ArtifactsSuite) TestResourceLogPlugin() { + s.Run("Basic", func() { + s.Given(). + Workflow(` +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: resource-tmpl-plugin-wf- +spec: + artifactRepositoryRef: + configMap: artifact-repositories + key: plugin-v1 + entrypoint: main + templates: + - name: main + resource: + action: create + successCondition: status.phase == Succeeded + setOwnerReference: true + manifest: | + apiVersion: argoproj.io/v1alpha1 + kind: Workflow + metadata: + generateName: hello-world-plugin- + labels: + workflows.argoproj.io/test: "true" + spec: + artifactRepositoryRef: + configMap: artifact-repositories + key: plugin-v1 + entrypoint: whalesay + templates: + - name: whalesay + container: + image: argoproj/argosay:v2 + command: [sh, -c] + args: [echo, ":) Hello Argo Plugin Resource!"] +`). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded). + Then(). + ExpectArtifact("-", "main-logs", "plugin-bucket", func(t *testing.T, object minio.ObjectInfo, err error) { + require.NoError(t, err) + s.checkArtifactContent(t, "plugin-bucket", object.Key, ":) Hello Argo Plugin Resource!") + }) + }) +} + func (s *ArtifactsSuite) TestContainersetLogs() { s.Run("Basic", func() { s.Given(). @@ -812,6 +1148,59 @@ spec: }) } +func (s *ArtifactsSuite) TestContainersetLogsPlugin() { + s.Run("Basic", func() { + s.Given(). + Workflow(` +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: containerset-logs-plugin- +spec: + entrypoint: main + artifactRepositoryRef: + configMap: artifact-repositories + key: plugin-v1 + templates: + - name: main + containerSet: + containers: + - name: a + image: argoproj/argosay:v2 + - name: b + image: argoproj/argosay:v2 +`). + When(). + SubmitWorkflow(). + WaitForWorkflow(fixtures.ToBeSucceeded). + Then(). + ExpectWorkflow(func(t *testing.T, m *metav1.ObjectMeta, status *wfv1.WorkflowStatus) { + n := status.Nodes[m.Name] + require.NotNil(t, n) + require.NotNil(t, n.Outputs) + + // Verify we have both log artifacts + assert.Len(t, n.Outputs.Artifacts, 2) + + // Check for a-logs artifact + aLogs := n.Outputs.GetArtifactByName("a-logs") + require.NotNil(t, aLogs, "a-logs artifact should exist") + require.NotNil(t, aLogs.Plugin, "a-logs should use plugin") + assert.Equal(t, fmt.Sprintf("%s/%s/a.log", m.Name, m.Name), aLogs.Plugin.Key) + + // Check for b-logs artifact + bLogs := n.Outputs.GetArtifactByName("b-logs") + require.NotNil(t, bLogs, "b-logs artifact should exist") + require.NotNil(t, bLogs.Plugin, "b-logs should use plugin") + assert.Equal(t, fmt.Sprintf("%s/%s/b.log", m.Name, m.Name), bLogs.Plugin.Key) + + // Verify the artifacts exist in the bucket and contain expected output + s.checkArtifactContent(t, "plugin-bucket", aLogs.Plugin.Key, "hello argo") + s.checkArtifactContent(t, "plugin-bucket", bLogs.Plugin.Key, "hello argo") + }) + }) +} + func (s *ArtifactsSuite) TestGitArtifactDepthClone() { s.Given(). Workflow(`apiVersion: argoproj.io/v1alpha1 @@ -879,6 +1268,46 @@ spec: WaitForWorkflow(fixtures.ToBeSucceeded) } +// checkArtifactContent reads an artifact from MinIO and verifies it contains expected content +func (s *ArtifactsSuite) checkArtifactContent(t *testing.T, bucketName, key, expectedContent string) { + t.Helper() + + // Create MinIO client + c, err := minio.New("localhost:9000", &minio.Options{ + Creds: credentials.NewStaticV4("admin", "password", ""), + }) + require.NoError(t, err) + + // Get the object + ctx := logging.TestContext(t.Context()) + obj, err := c.GetObject(ctx, bucketName, key, minio.GetObjectOptions{}) + require.NoError(t, err) + defer obj.Close() + + // Read the content + content, err := io.ReadAll(obj) + require.NoError(t, err) + + var contentStr string + // Check if content is gzipped (artifacts may be compressed) + if len(content) > 2 && content[0] == 0x1f && content[1] == 0x8b { + // Content is gzipped, decompress it + gzipReader, err := gzip.NewReader(bytes.NewReader(content)) + require.NoError(t, err, "Failed to create gzip reader") + defer gzipReader.Close() + + decompressed, err := io.ReadAll(gzipReader) + require.NoError(t, err, "Failed to decompress gzipped content") + contentStr = string(decompressed) + } else { + // Content is not compressed, use as-is + contentStr = string(content) + } + + // Check that the expected content is present + assert.Contains(t, contentStr, expectedContent, "Artifact content should contain expected text") +} + func TestArtifactsSuite(t *testing.T) { suite.Run(t, new(ArtifactsSuite)) } diff --git a/test/e2e/expectedfailures/timeouts-step-plugin.yaml b/test/e2e/expectedfailures/timeouts-step-plugin.yaml new file mode 100644 index 000000000000..f133c3adee8c --- /dev/null +++ b/test/e2e/expectedfailures/timeouts-step-plugin.yaml @@ -0,0 +1,20 @@ +# To enforce a timeout to a template, specify a value for activeDeadlineSeconds. +# This value represents the duration in seconds relative to the pod StartTime +# that the pod may be active on a node before the system actively tries to +# terminate it. This field is only applicable to container and script templates. +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: timeouts-step-plugin- +spec: + entrypoint: sleep + artifactRepositoryRef: + configMap: artifact-repositories + key: plugin-v1 + templates: + - name: sleep + container: + image: argoproj/argosay:v2 + command: [bash, -c] + args: ["echo 123; sleep 1d"] + activeDeadlineSeconds: 10 diff --git a/test/e2e/fixtures/then.go b/test/e2e/fixtures/then.go index 84ccb57fe0a0..f3cb71d37362 100644 --- a/test/e2e/fixtures/then.go +++ b/test/e2e/fixtures/then.go @@ -245,8 +245,13 @@ func (t *Then) ExpectArtifact(nodeName string, artifactName string, bucketName s n, err := t.wf.GetNodeByName(nodeName) if err != nil { t.t.Error("was unable to get node by name") + return } a := n.GetOutputs().GetArtifactByName(artifactName) + if a == nil { + t.t.Error("was unable to get artifact by name") + return + } key, _ := a.GetKey() t.ExpectArtifactByKey(key, bucketName, f) diff --git a/test/e2e/manifests/components/base/minio-deployment.yaml b/test/e2e/manifests/components/base/minio-deployment.yaml index 4490d232f43a..12f616a0542a 100644 --- a/test/e2e/manifests/components/base/minio-deployment.yaml +++ b/test/e2e/manifests/components/base/minio-deployment.yaml @@ -10,6 +10,4 @@ spec: lifecycle: postStart: exec: - command: ["mkdir", "-p", "/data/my-bucket", "&&", "mkdir", "-p", "/data/my-bucket-2", "&&", "mkdir", "-p", "/data/my-bucket-3"] - - \ No newline at end of file + command: ["mkdir", "-p", "/data/my-bucket", "&&", "mkdir", "-p", "/data/my-bucket-2", "&&", "mkdir", "-p", "/data/my-bucket-3", "&&", "mkdir", "-p", "/data/plugin-bucket"] diff --git a/test/e2e/manifests/components/base/workflow-controller-configmap.yaml b/test/e2e/manifests/components/base/workflow-controller-configmap.yaml index cc3cd851bf65..9c40799c7951 100644 --- a/test/e2e/manifests/components/base/workflow-controller-configmap.yaml +++ b/test/e2e/manifests/components/base/workflow-controller-configmap.yaml @@ -7,7 +7,7 @@ data: spec: activeDeadlineSeconds: 300 podSpecPatch: | - terminationGracePeriodSeconds: 3 + terminationGracePeriodSeconds: 10 workflowMetadata: labels: default-label: thisLabelIsFromWorkflowDefaults @@ -24,3 +24,6 @@ data: completed: 10 failed: 2 errored: 2 + artifactDrivers: | + - name: test + image: ghcr.io/argoproj-labs/artifact-driver-s3:v0.3.1 diff --git a/test/e2e/testdata/artifact-passing-plugin-workflow.yaml b/test/e2e/testdata/artifact-passing-plugin-workflow.yaml new file mode 100644 index 000000000000..40e54e2b7447 --- /dev/null +++ b/test/e2e/testdata/artifact-passing-plugin-workflow.yaml @@ -0,0 +1,41 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: artifact-passing-plugin- +spec: + entrypoint: main + artifactRepositoryRef: + configMap: artifact-repositories + key: plugin-v1 + templates: + - name: main + dag: + tasks: + - name: generate-artifact + template: generate-message + - name: consume-artifact + template: print-message + dependencies: + - generate-artifact + arguments: + artifacts: + - name: in + from: "{{tasks.generate-artifact.outputs.artifacts.out}}" + + - name: generate-message + container: + image: argoproj/argosay:v2 + args: [ "echo", "hello world", "/mnt/out/message" ] + outputs: + artifacts: + - name: out + path: /mnt/out + + - name: print-message + inputs: + artifacts: + - name: in + path: /mnt/in + container: + image: argoproj/argosay:v2 + args: [ "cat", "/mnt/in/message" ] diff --git a/test/e2e/testdata/artifactgc/artgc-artifact-not-written-failed-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-artifact-not-written-failed-plugin.yaml new file mode 100644 index 000000000000..4b8ed3638532 --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-artifact-not-written-failed-plugin.yaml @@ -0,0 +1,40 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: artgc-artifact-not-written-failed-plugin- +spec: + entrypoint: main + artifactGC: + strategy: OnWorkflowDeletion + templates: + - name: main + container: + image: argoproj/argosay:v2 + command: + - sh + - -c + args: + - | + echo "intentionally not writing anything to disk and intentional failure" + exit 1 + outputs: + artifacts: + - name: on-completion + path: /tmp/on-completion.txt + archive: + none: {} + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: on-completion.txt + artifactGC: + strategy: OnWorkflowCompletion diff --git a/test/e2e/testdata/artifactgc/artgc-dag-wf-self-delete-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-dag-wf-self-delete-plugin.yaml new file mode 100644 index 000000000000..06aa5977d563 --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-dag-wf-self-delete-plugin.yaml @@ -0,0 +1,104 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: artgc-dag-wf-self-delete-plugin- +spec: + workflowMetadata: + labels: + workflows.argoproj.io/test: "true" + workflows.argoproj.io/workflow: "artgc-dag-wf-self-delete-plugin" + podGC: + strategy: OnPodCompletion + artifactGC: + serviceAccountName: default + strategy: OnWorkflowDeletion + entrypoint: artgc-dag-wf-self-delete-main + serviceAccountName: argo + executor: + serviceAccountName: default + volumeClaimTemplates: + - metadata: + name: artifacts + spec: + accessModes: [ "ReadWriteOnce" ] + resources: + requests: + storage: 1Gi + templates: + - name: artgc-dag-wf-self-delete-main + dag: + tasks: + - name: create-artifact + template: artgc-dag-artifact-creator + - name: delay-delete-workflow + template: artgc-dag-delay-delete + dependencies: [create-artifact] + - name: delete-workflow + template: artgc-dag-workflow-deleter + dependencies: [delay-delete-workflow] + - name: artgc-dag-delay-delete + container: + image: argoproj/argosay:v2 + volumeMounts: + - name: artifacts + mountPath: /mnt/vol + command: [sh, -c] + args: + - | + echo "Delaying workflow delete" + ls /mnt + x=0 + while [ $x -le 60 ] + do + sleep 1 + if [ -f "/mnt/vol/test.txt" ]; then + echo "Artifacts found in shared volume" + break + fi + x=$(( $x + 1 )) + done + - name: artgc-dag-workflow-deleter + container: + image: quay.io/argoproj/argocli:latest + imagePullPolicy: Never + args: + - delete + - -l + - workflows.argoproj.io/workflow=artgc-dag-wf-self-delete-plugin + - --namespace=argo + - --loglevel=debug + - name: artgc-dag-artifact-creator + metadata: + labels: + template: "artgc-dag-artifact-creator" + container: + image: argoproj/argosay:v2 + volumeMounts: + - name: artifacts + mountPath: /mnt/vol + command: [sh, -c] + args: + - | + echo 'testing plugin' > /mnt/vol/test.txt + echo "Artifact saved to /mnt/vol/test.txt" + outputs: + artifacts: + - name: artifact + path: /mnt/vol/test.txt + archive: + none: {} + plugin: + name: test + key: artifact-plugin + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + artifactGC: + strategy: OnWorkflowDeletion diff --git a/test/e2e/testdata/artifactgc/artgc-from-ref-template-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-from-ref-template-plugin.yaml new file mode 100644 index 000000000000..c663fc9c2061 --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-from-ref-template-plugin.yaml @@ -0,0 +1,8 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: artgc-from-template-plugin- +spec: + workflowTemplateRef: + name: artgc-template-ref-template-plugin + clusterScope: false diff --git a/test/e2e/testdata/artifactgc/artgc-from-template-2-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-from-template-2-plugin.yaml new file mode 100644 index 000000000000..49bf4e21065d --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-from-template-2-plugin.yaml @@ -0,0 +1,8 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: artgc-from-template-2-plugin- +spec: + workflowTemplateRef: + name: artgc-template-2-plugin + clusterScope: false diff --git a/test/e2e/testdata/artifactgc/artgc-from-template-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-from-template-plugin.yaml new file mode 100644 index 000000000000..c16e5ecffe08 --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-from-template-plugin.yaml @@ -0,0 +1,8 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: artgc-from-template-plugin- +spec: + workflowTemplateRef: + name: artgc-template-plugin + clusterScope: false diff --git a/test/e2e/testdata/artifactgc/artgc-multi-strategy-multi-anno-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-multi-strategy-multi-anno-plugin.yaml new file mode 100644 index 000000000000..2e45a7b98077 --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-multi-strategy-multi-anno-plugin.yaml @@ -0,0 +1,141 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: testing-on-completion-and-on-deletion-strategies-plugin- +spec: + entrypoint: entrypoint + artifactGC: + strategy: OnWorkflowCompletion + podGC: + strategy: "" + templates: + - name: entrypoint + steps: + - - name: call-first + template: first + - - name: call-second + template: second + - name: first + container: + image: argoproj/argosay:v2 + command: + - sh + - -c + args: + - | + echo "hello world" > /tmp/message + outputs: + artifacts: + - name: first-on-completion-1 + path: /tmp/message + archive: + none: {} + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: first-on-completion-1 + artifactGC: + strategy: OnWorkflowCompletion + serviceAccountName: default + podMetadata: + annotations: + annotation-key-1: annotation-value-1 + annotation-key-2: annotation-value-2 + - name: first-on-completion-2 + path: /tmp/message + archive: + none: {} + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: first-on-completion-2 + - name: first-no-deletion + path: /tmp/message + archive: + none: {} + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: first-no-deletion + artifactGC: + strategy: Never + + - name: second + archiveLocation: + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: default-to-be-overridden + container: + image: argoproj/argosay:v2 + command: + - sh + - -c + args: + - | + echo "hello world" > /tmp/message + outputs: + artifacts: + - name: second-on-deletion + path: /tmp/message + archive: + none: {} + plugin: + key: second-on-deletion + artifactGC: + strategy: OnWorkflowDeletion + - name: second-on-completion + path: /tmp/message + archive: + none: {} + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: second-on-completion + artifactGC: + strategy: OnWorkflowCompletion diff --git a/test/e2e/testdata/artifactgc/artgc-non-optional-artifact-not-written-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-non-optional-artifact-not-written-plugin.yaml new file mode 100644 index 000000000000..03843a3b376e --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-non-optional-artifact-not-written-plugin.yaml @@ -0,0 +1,79 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: artgc-non-optional-artifact-not-written-plugin- +spec: + entrypoint: entrypoint + artifactGC: + strategy: OnWorkflowDeletion + podGC: + strategy: "" + templates: + - name: entrypoint + steps: + - - name: artifact-written + template: artifact-written + - - name: some-artifacts-not-written + template: some-artifacts-not-written + - name: artifact-written + archiveLocation: + plugin: + name: test + key: "{{workflow.name}}" + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + container: + image: argoproj/argosay:v2 + command: + - sh + - -c + args: + - | + echo "something" > /tmp/present + outputs: + artifacts: + - name: present + path: /tmp/present + archive: + none: {} + - name: some-artifacts-not-written + archiveLocation: + plugin: + name: test + key: "{{workflow.name}}" + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + container: + image: argoproj/argosay:v2 + command: + - sh + - -c + args: + - | + echo "something" > /tmp/present + outputs: + artifacts: + - name: notpresent + path: /tmp/notpresent + archive: + none: {} + - name: present + path: /tmp/present + archive: + none: {} diff --git a/test/e2e/testdata/artifactgc/artgc-optional-artifact-not-written-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-optional-artifact-not-written-plugin.yaml new file mode 100644 index 000000000000..983048f00628 --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-optional-artifact-not-written-plugin.yaml @@ -0,0 +1,80 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: artgc-optional-artifact-not-written-plugin- +spec: + entrypoint: entrypoint + artifactGC: + strategy: OnWorkflowDeletion + podGC: + strategy: "" + templates: + - name: entrypoint + steps: + - - name: some-artifacts-not-written + template: some-artifacts-not-written + - - name: artifact-written + template: artifact-written + - name: some-artifacts-not-written + archiveLocation: + plugin: + name: test + key: "{{workflow.name}}" + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + container: + image: argoproj/argosay:v2 + command: + - sh + - -c + args: + - | + echo "something" > /tmp/present + outputs: + artifacts: + - name: notpresent + path: /tmp/notpresent + optional: true + archive: + none: {} + - name: present + path: /tmp/present + archive: + none: {} + - name: artifact-written + archiveLocation: + plugin: + name: test + key: "{{workflow.name}}" + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + container: + image: argoproj/argosay:v2 + command: + - sh + - -c + args: + - | + echo "something" > /tmp/present + outputs: + artifacts: + - name: present + path: /tmp/present + archive: + none: {} diff --git a/test/e2e/testdata/artifactgc/artgc-step-wf-tmpl-2-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-step-wf-tmpl-2-plugin.yaml new file mode 100644 index 000000000000..d136b768873f --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-step-wf-tmpl-2-plugin.yaml @@ -0,0 +1,14 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: artgc-step-wf-tmpl-plugin- +spec: + entrypoint: artgc-step-wf-tmpl + templates: + - name: artgc-step-wf-tmpl + steps: + - - name: call-template + templateRef: + name: artgc-template-2-plugin + template: artgc-template-main + clusterScope: false diff --git a/test/e2e/testdata/artifactgc/artgc-step-wf-tmpl-no-gc-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-step-wf-tmpl-no-gc-plugin.yaml new file mode 100644 index 000000000000..e51a19d0c6ef --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-step-wf-tmpl-no-gc-plugin.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: artgc-step-wf-tmpl-no-gc-plugin- +spec: + artifactGC: + strategy: OnWorkflowDeletion + entrypoint: artgc-step-wf-tmpl-no-gc + templates: + - name: artgc-step-wf-tmpl-no-gc + steps: + - - name: call-template + templateRef: + name: artgc-template-no-gc-plugin + template: artgc-template-main + clusterScope: false diff --git a/test/e2e/testdata/artifactgc/artgc-step-wf-tmpl-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-step-wf-tmpl-plugin.yaml new file mode 100644 index 000000000000..0db4a79e9ba5 --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-step-wf-tmpl-plugin.yaml @@ -0,0 +1,14 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: artgc-step-wf-tmpl-plugin- +spec: + entrypoint: artgc-step-wf-tmpl + templates: + - name: artgc-step-wf-tmpl + steps: + - - name: call-template + templateRef: + name: artgc-template-plugin + template: artgc-template-main + clusterScope: false diff --git a/test/e2e/testdata/artifactgc/artgc-template-2-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-template-2-plugin.yaml new file mode 100644 index 000000000000..0f3a13d8497e --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-template-2-plugin.yaml @@ -0,0 +1,60 @@ +apiVersion: argoproj.io/v1alpha1 +kind: WorkflowTemplate +metadata: + name: artgc-template-2-plugin +spec: + artifactGC: + strategy: OnWorkflowDeletion + workflowMetadata: + labels: + workflows.argoproj.io/test: "true" + entrypoint: artgc-template-main + templates: + - name: artgc-template-main + container: + image: argoproj/argosay:v2 + command: + - sh + - -c + args: + - | + echo "hello world" + echo "hello world" > /tmp/message + outputs: + artifacts: + - name: on-completion + path: /tmp/message + archive: + none: {} + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: on-completion + artifactGC: + strategy: OnWorkflowCompletion + - name: on-deletion + path: /tmp/message + archive: + none: {} + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: on-deletion diff --git a/test/e2e/testdata/artifactgc/artgc-template-no-gc-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-template-no-gc-plugin.yaml new file mode 100644 index 000000000000..03b56df7efe8 --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-template-no-gc-plugin.yaml @@ -0,0 +1,62 @@ +apiVersion: argoproj.io/v1alpha1 +kind: WorkflowTemplate +metadata: + name: artgc-template-no-gc-plugin +spec: + artifactGC: + strategy: OnWorkflowDeletion + workflowMetadata: + labels: + workflows.argoproj.io/test: "true" + entrypoint: artgc-template-main + templates: + - name: artgc-template-main + container: + image: argoproj/argosay:v2 + command: + - sh + - -c + args: + - | + echo "hello world" + echo "hello world" > /tmp/message + outputs: + artifacts: + - name: on-completion + path: /tmp/message + archive: + none: {} + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: on-completion + artifactGC: + strategy: Never + - name: on-deletion + path: /tmp/message + archive: + none: {} + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: on-deletion + artifactGC: + strategy: Never diff --git a/test/e2e/testdata/artifactgc/artgc-template-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-template-plugin.yaml new file mode 100644 index 000000000000..429d25984ce6 --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-template-plugin.yaml @@ -0,0 +1,60 @@ +apiVersion: argoproj.io/v1alpha1 +kind: WorkflowTemplate +metadata: + name: artgc-template-plugin +spec: + workflowMetadata: + labels: + workflows.argoproj.io/test: "true" + entrypoint: artgc-template-main + templates: + - name: artgc-template-main + container: + image: argoproj/argosay:v2 + command: + - sh + - -c + args: + - | + echo "hello world" + echo "hello world" > /tmp/message + outputs: + artifacts: + - name: on-completion + path: /tmp/message + archive: + none: {} + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: on-completion + artifactGC: + strategy: OnWorkflowCompletion + - name: on-deletion + path: /tmp/message + archive: + none: {} + plugin: + name: test + configuration: | + bucket: plugin-bucket + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: on-deletion + artifactGC: + strategy: OnWorkflowDeletion diff --git a/test/e2e/testdata/artifactgc/artgc-template-ref-template-plugin.yaml b/test/e2e/testdata/artifactgc/artgc-template-ref-template-plugin.yaml new file mode 100644 index 000000000000..d44e0e07ae1c --- /dev/null +++ b/test/e2e/testdata/artifactgc/artgc-template-ref-template-plugin.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1alpha1 +kind: WorkflowTemplate +metadata: + name: artgc-template-ref-template-plugin +spec: + entrypoint: steps-direct + artifactGC: + strategy: OnWorkflowDeletion + + templates: + - name: steps-direct + steps: + - - name: main + templateRef: + name: artgc-template-plugin + template: artgc-template-main diff --git a/test/e2e/testdata/complex-global-artifact-passing-plugin.yaml b/test/e2e/testdata/complex-global-artifact-passing-plugin.yaml new file mode 100644 index 000000000000..3bdf14ac18fc --- /dev/null +++ b/test/e2e/testdata/complex-global-artifact-passing-plugin.yaml @@ -0,0 +1,209 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: global-artifact-passing-plugin- +spec: + entrypoint: test-root + artifactRepositoryRef: + key: plugin-v1 + templates: + - inputs: {} + metadata: {} + name: test-root + outputs: {} + steps: + - - arguments: {} + name: create-global-artifacts + template: create-global-artifacts + - - arguments: + artifacts: + - from: '{{workflow.outputs.artifacts.testInput}}' + name: testInput + - from: '{{workflow.outputs.artifacts.testUpdate}}' + name: testUpdate + name: nested-workflow-entrypoint + template: main + - - arguments: + artifacts: + - from: '{{workflow.outputs.artifacts.testUpload}}' + name: testUpload + name: upload-testupload-step + template: upload-testupload + - - arguments: + artifacts: + - from: '{{workflow.outputs.artifacts.testUpdate}}' + name: testUpdate + name: upload-testupdate-step + template: upload-testupdate + + - inputs: {} + metadata: {} + name: main + outputs: {} + steps: + - - arguments: + artifacts: + - from: '{{workflow.outputs.artifacts.testInput}}' + name: input + name: cp + template: cp + - - arguments: + artifacts: + - from: '{{workflow.outputs.artifacts.testUpdate}}' + name: input-parameters + name: generate-testupdate-update + template: generate-testupdate-update + - - arguments: + artifacts: + - from: '{{steps.cp.outputs.artifacts.upload}}' + name: testUpload + name: output-testupload + template: output-testupload + - - arguments: + artifacts: + - from: '{{steps.generate-testupdate-update.outputs.artifacts.updated-testupdate}}' + name: testUpdate + name: output-testupdate + template: output-testupdate + + + + - container: + image: argoproj/argosay:v2 + command: [sh, -c] + args: ["sleep 1; echo -n 'test input' > /testInput.txt; echo -n 'test update' > /testUpdate.txt"] + name: create-global-artifacts + outputs: + artifacts: + - globalName: testInput + name: testInput + path: /testInput.txt + archive: + none: {} + - globalName: testUpdate + name: testUpdate + path: /testUpdate.txt + archive: + none: {} + + + + - container: + image: argoproj/argosay:v2 + command: [sh, -c] + args: ["sleep 1; cp /input.txt /upload.txt"] + name: "" + resources: {} + inputs: + artifacts: + - name: input + path: /input.txt + metadata: {} + name: cp + outputs: + artifacts: + - name: upload + path: /upload.txt + + - container: + image: argoproj/argosay:v2 + command: [sh, -c] + args: ["sleep 1; echo -n 'Updated testUpdate' > /updated-testUpdate.txt"] + metadata: {} + name: generate-testupdate-update + outputs: + artifacts: + - name: updated-testupdate + path: /updated-testUpdate.txt + archive: + none: {} + + - container: + image: argoproj/argosay:v2 + command: [sh, -c] + args: ["sleep 1"] + name: "" + resources: {} + inputs: + artifacts: + - name: testUpload + path: /testUpload.txt + metadata: {} + name: output-testupload + outputs: + artifacts: + - globalName: testUpload + name: testUpload + path: /testUpload.txt + + - container: + image: argoproj/argosay:v2 + command: [sh, -c] + args: ["sleep 1"] + name: "" + resources: {} + inputs: + artifacts: + - name: testUpdate + path: /testUpdate.txt + metadata: {} + name: output-testupdate + outputs: + artifacts: + - globalName: testUpdate + name: testUpdate + path: /testUpdate.txt + + + + - container: + image: argoproj/argosay:v2 + command: [sh, -c] + args: ["sleep 1; cat /upload/testInput.txt > /upload/testUpload.txt"] + name: "" + resources: {} + inputs: + artifacts: + - name: testUpload + path: /upload/testInput.txt + metadata: {} + name: upload-testupload + outputs: + artifacts: + - globalName: uploadresult + name: uploadresult + path: /upload/testUpload.txt + + - container: + image: argoproj/argosay:v2 + command: [sh, -c] + args: ["sleep 1; cat /upload/testUpdate.txt"] + name: "" + resources: {} + inputs: + artifacts: + - name: testUpdate + path: /upload/testUpdate.txt + metadata: {} + name: upload-testupdate + outputs: + artifacts: + - name: finalTestUpdate + path: /upload/testUpdate.txt + archive: + none: {} + plugin: + name: test + configuration: | + bucket: my-bucket-3 + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: finalTestUpdatePlugin + artifactGC: + strategy: OnWorkflowDeletion diff --git a/test/e2e/testdata/default-params-plugin-workflow.yaml b/test/e2e/testdata/default-params-plugin-workflow.yaml new file mode 100644 index 000000000000..3e5d9c8dd711 --- /dev/null +++ b/test/e2e/testdata/default-params-plugin-workflow.yaml @@ -0,0 +1,43 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: default-params-plugin- +spec: + artifactRepositoryRef: + configMap: artifact-repositories + key: plugin-v1 + entrypoint: start + templates: + - name: start + steps: + - - name: generate-1 + template: generate + - - name: generate-2 + when: "True == False" + template: generate + outputs: + parameters: + - name: nested-out-parameter + valueFrom: + default: "Default value" + parameter: "{{steps.generate-2.outputs.parameters.out-parameter}}" + artifacts: + - name: output-artifact + from: "{{steps.generate-1.outputs.artifacts.test-artifact}}" + archive: + none: {} + + - name: generate + container: + image: argoproj/argosay:v2 + args: [echo, my-output-parameter, /tmp/my-output-parameter.txt] + outputs: + parameters: + - name: out-parameter + valueFrom: + path: /tmp/my-output-parameter.txt + artifacts: + - name: test-artifact + path: /tmp/my-output-parameter.txt + archive: + none: {} diff --git a/test/e2e/testdata/global-artifact-passing-plugin.yaml b/test/e2e/testdata/global-artifact-passing-plugin.yaml new file mode 100644 index 000000000000..acffcab381ab --- /dev/null +++ b/test/e2e/testdata/global-artifact-passing-plugin.yaml @@ -0,0 +1,96 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: global-artifact-passing-plugin- +spec: + entrypoint: main + artifactRepositoryRef: + key: plugin-v1 + templates: + - name: main + outputs: {} + steps: + - - name: create-global-artifact + template: create-global-artifact + - - name: add-0 + template: add-to-global-artifact + arguments: + artifacts: + - name: input + from: '{{workflow.outputs.artifacts.globalArtifact}}' + parameters: + - name: value + value: '0' + - - name: add-1 + template: add-to-global-artifact + arguments: + artifacts: + - name: input + from: '{{workflow.outputs.artifacts.globalArtifact}}' + parameters: + - name: value + value: '1' + - - name: save-artifact + template: save-artifact + arguments: + artifacts: + - name: input + from: '{{workflow.outputs.artifacts.globalArtifact}}' + - name: create-global-artifact + container: + image: argoproj/argosay:v2 + command: [sh, -c] + args: ["touch /tmp/artifact.txt"] + outputs: + artifacts: + - globalName: globalArtifact + name: artifact + path: /tmp/artifact.txt + archive: + none: {} + - name: add-to-global-artifact + inputs: + parameters: + - name: value + artifacts: + - name: input + path: /tmp/artifact.txt + outputs: + artifacts: + - globalName: globalArtifact + name: artifact + path: /tmp/artifact.txt + archive: + none: {} + container: + image: argoproj/argosay:v2 + command: [sh, -c] + args: ["sleep 10; echo -n {{inputs.parameters.value}} >> /tmp/artifact.txt; echo frogs; cat /tmp/artifact.txt;echo dogs;cat /tmp/artifact.txt;echo pogs;sleep 10;"] + - name: save-artifact + container: + image: argoproj/argosay:v2 + inputs: + artifacts: + - name: input + path: /tmp/artifact.txt + outputs: + artifacts: + - name: globalArtifact + path: /tmp/artifact.txt + archive: + none: {} + plugin: + name: test + configuration: | + bucket: my-bucket-3 + endpoint: minio:9000 + insecure: true + accessKeySecret: + name: my-minio-cred + key: accesskey + secretKeySecret: + name: my-minio-cred + key: secretkey + key: globalArtifactPlugin + artifactGC: + strategy: OnWorkflowDeletion diff --git a/test/e2e/testdata/input-on-mount-plugin-workflow.yaml b/test/e2e/testdata/input-on-mount-plugin-workflow.yaml new file mode 100644 index 000000000000..8b968d44f8d6 --- /dev/null +++ b/test/e2e/testdata/input-on-mount-plugin-workflow.yaml @@ -0,0 +1,44 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: input-on-mount-plugin- +spec: + entrypoint: main + artifactRepositoryRef: + configMap: artifact-repositories + key: plugin-v1 + templates: + - name: main + steps: + - - name: create-artifact + template: create + - - name: read-artifact + template: read + arguments: + artifacts: + - name: in-0 + from: "{{steps.create-artifact.outputs.artifacts.artifact}}" + - name: create + container: + image: argoproj/argosay:v2 + args: [ echo, "hello plugin mount", /tmp/input.txt ] + outputs: + artifacts: + - name: artifact + path: /tmp/input.txt + archive: + none: {} + - name: read + volumes: + - name: mnt + emptyDir: { } + container: + image: argoproj/argosay:v2 + args: [ cat , /mnt/in-0 ] + volumeMounts: + - name: mnt + mountPath: /mnt + inputs: + artifacts: + - name: in-0 + path: /mnt/in-0 diff --git a/test/e2e/testdata/main-log-plugin-workflow.yaml b/test/e2e/testdata/main-log-plugin-workflow.yaml new file mode 100644 index 000000000000..1193b89a8c20 --- /dev/null +++ b/test/e2e/testdata/main-log-plugin-workflow.yaml @@ -0,0 +1,16 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: main-log-plugin- +spec: + entrypoint: main + artifactRepositoryRef: + configMap: artifact-repositories + key: plugin-v1 + templates: + - name: main + container: + image: argoproj/argosay:v2 + args: + - echo + - ":) Hello Argo Plugin Logs!" diff --git a/test/e2e/testdata/output-on-input-plugin-workflow.yaml b/test/e2e/testdata/output-on-input-plugin-workflow.yaml new file mode 100644 index 000000000000..70a92654f0ad --- /dev/null +++ b/test/e2e/testdata/output-on-input-plugin-workflow.yaml @@ -0,0 +1,27 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: output-on-input-plugin- +spec: + entrypoint: main + artifactRepositoryRef: + configMap: artifact-repositories + key: plugin-v1 + templates: + - name: main + container: + image: argoproj/argosay:v2 + args: [ echo, hi, /file ] + inputs: + artifacts: + - name: in-0 + path: /file + raw: + data: hi + outputs: + artifacts: + - name: out-0 + path: /file + archive: + none: {} + diff --git a/test/e2e/testdata/output-on-mount-plugin-workflow.yaml b/test/e2e/testdata/output-on-mount-plugin-workflow.yaml new file mode 100644 index 000000000000..85c99fe8f4f1 --- /dev/null +++ b/test/e2e/testdata/output-on-mount-plugin-workflow.yaml @@ -0,0 +1,26 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: output-on-mount-plugin- +spec: + entrypoint: main + artifactRepositoryRef: + configMap: artifact-repositories + key: plugin-v1 + templates: + - name: main + volumes: + - name: mnt + emptyDir: { } + container: + image: argoproj/argosay:v2 + args: [ echo , hi, /mnt/out-0 ] + volumeMounts: + - name: mnt + mountPath: /mnt + outputs: + artifacts: + - name: out-0 + path: /mnt/out-0 + archive: + none: {} diff --git a/test/e2e/testdata/same-input-output-path-optional-plugin.yaml b/test/e2e/testdata/same-input-output-path-optional-plugin.yaml new file mode 100644 index 000000000000..12c0eb93c3a0 --- /dev/null +++ b/test/e2e/testdata/same-input-output-path-optional-plugin.yaml @@ -0,0 +1,23 @@ +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: optional-input-output-artifact-same-location-plugin- +spec: + entrypoint: main + artifactRepositoryRef: + configMap: artifact-repositories + key: plugin-v1 + templates: + - name: main + inputs: + artifacts: + - name: file + path: /tmp/file1.txt + optional: true + container: + image: argoproj/argosay:v2 + args: ["echo", "test", "/tmp/file1.txt"] + outputs: + artifacts: + - name: file + path: /tmp/file1.txt diff --git a/util/k8s/pod.go b/util/k8s/pod.go new file mode 100644 index 000000000000..7ccce91a70c1 --- /dev/null +++ b/util/k8s/pod.go @@ -0,0 +1,46 @@ +package k8s + +import ( + "context" + "fmt" + "os" + + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes" + + "github.com/argoproj/argo-workflows/v3/workflow/common" +) + +// GetCurrentPodName returns the name of the current pod using the standard +// Argo Workflows pattern. It first tries to get the pod name from the +// ARGO_POD_NAME environment variable (set via Downward API), and falls back +// to using the Kubernetes client to find the pod by label selector. +func GetCurrentPodName(ctx context.Context, client kubernetes.Interface, namespace, labelSelector string) (string, error) { + // First try the standard Argo environment variable + if podName := os.Getenv(common.EnvVarPodName); podName != "" { + return podName, nil + } + + // Fallback: use Kubernetes client to find pod by label selector + podList, err := client.CoreV1().Pods(namespace).List(ctx, metav1.ListOptions{ + LabelSelector: labelSelector, + }) + if err != nil { + return "", fmt.Errorf("failed to list pods with selector %s: %w", labelSelector, err) + } + + if len(podList.Items) == 0 { + return "", fmt.Errorf("no pods found with selector: %s", labelSelector) + } + + // Find the first running pod + for _, pod := range podList.Items { + if pod.Status.Phase == v1.PodRunning { + return pod.Name, nil + } + } + + // If no running pods, return the first pod found + return podList.Items[0].Name, nil +} diff --git a/util/k8s/pod_test.go b/util/k8s/pod_test.go new file mode 100644 index 000000000000..1c4a34a66627 --- /dev/null +++ b/util/k8s/pod_test.go @@ -0,0 +1,87 @@ +package k8s + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + v1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/client-go/kubernetes/fake" + + "github.com/argoproj/argo-workflows/v3/util/logging" + "github.com/argoproj/argo-workflows/v3/workflow/common" +) + +func TestGetCurrentPodName(t *testing.T) { + ctx := logging.TestContext(t.Context()) + + t.Run("Returns pod name from environment variable", func(t *testing.T) { + t.Setenv(common.EnvVarPodName, "test-pod-from-env") + + client := fake.NewSimpleClientset() + podName, err := GetCurrentPodName(ctx, client, "test-namespace", "app=test") + + require.NoError(t, err) + assert.Equal(t, "test-pod-from-env", podName) + }) + + t.Run("Falls back to Kubernetes client when env var not set", func(t *testing.T) { + // Ensure env var is not set + t.Setenv(common.EnvVarPodName, "") + + // Create a fake pod + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod-from-k8s", + Namespace: "test-namespace", + Labels: map[string]string{ + "app": "test", + }, + }, + Status: v1.PodStatus{ + Phase: v1.PodRunning, + }, + } + + client := fake.NewSimpleClientset(pod) + podName, err := GetCurrentPodName(ctx, client, "test-namespace", "app=test") + + require.NoError(t, err) + assert.Equal(t, "test-pod-from-k8s", podName) + }) + + t.Run("Returns first pod when no running pods found", func(t *testing.T) { + t.Setenv(common.EnvVarPodName, "") + + // Create a fake pod that's not running + pod := &v1.Pod{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-pod-pending", + Namespace: "test-namespace", + Labels: map[string]string{ + "app": "test", + }, + }, + Status: v1.PodStatus{ + Phase: v1.PodPending, + }, + } + + client := fake.NewSimpleClientset(pod) + podName, err := GetCurrentPodName(ctx, client, "test-namespace", "app=test") + + require.NoError(t, err) + assert.Equal(t, "test-pod-pending", podName) + }) + + t.Run("Returns error when no pods found", func(t *testing.T) { + t.Setenv(common.EnvVarPodName, "") + + client := fake.NewSimpleClientset() + _, err := GetCurrentPodName(ctx, client, "test-namespace", "app=nonexistent") + + require.Error(t, err) + assert.Contains(t, err.Error(), "no pods found with selector") + }) +} diff --git a/workflow/artifacts/artifacts.go b/workflow/artifacts/artifacts.go index 5c897bec3c1d..7246f5343c36 100644 --- a/workflow/artifacts/artifacts.go +++ b/workflow/artifacts/artifacts.go @@ -1,4 +1,4 @@ -package executor +package artifacts import ( "context" @@ -14,6 +14,7 @@ import ( "github.com/argoproj/argo-workflows/v3/workflow/artifacts/http" "github.com/argoproj/argo-workflows/v3/workflow/artifacts/logging" "github.com/argoproj/argo-workflows/v3/workflow/artifacts/oss" + "github.com/argoproj/argo-workflows/v3/workflow/artifacts/plugin" "github.com/argoproj/argo-workflows/v3/workflow/artifacts/raw" "github.com/argoproj/argo-workflows/v3/workflow/artifacts/resource" "github.com/argoproj/argo-workflows/v3/workflow/artifacts/s3" @@ -32,6 +33,7 @@ func NewDriver(ctx context.Context, art *wfv1.Artifact, ri resource.Interface) ( return logging.New(drv), nil } + func newDriver(ctx context.Context, art *wfv1.Artifact, ri resource.Interface) (common.ArtifactDriver, error) { if art.S3 != nil { var accessKey string @@ -274,5 +276,15 @@ func newDriver(ctx context.Context, art *wfv1.Artifact, ri resource.Interface) ( return &driver, nil } + if art.Plugin != nil { + // Get the socket path from the driver configuration + // This would typically come from the workflow controller configuration + driver, err := plugin.NewDriver(ctx, art.Plugin.Name, art.Plugin.Name.SocketPath(), art.Plugin.ConnectionTimeoutSeconds) + if err != nil { + return nil, fmt.Errorf("failed to create plugin driver for %s: %w", art.Plugin.Name, err) + } + return driver, nil + } + return nil, ErrUnsupportedDriver } diff --git a/workflow/artifacts/artifacts_test.go b/workflow/artifacts/artifacts_test.go index 83b10236d288..1a76a80eacaa 100644 --- a/workflow/artifacts/artifacts_test.go +++ b/workflow/artifacts/artifacts_test.go @@ -1,4 +1,4 @@ -package executor +package artifacts import ( "context" diff --git a/workflow/artifacts/plugin/plugin.go b/workflow/artifacts/plugin/plugin.go new file mode 100644 index 000000000000..a1eff93cbcc5 --- /dev/null +++ b/workflow/artifacts/plugin/plugin.go @@ -0,0 +1,287 @@ +package plugin + +import ( + "context" + "fmt" + "io" + "net" + "os" + "time" + + "google.golang.org/grpc" + "google.golang.org/grpc/connectivity" + "google.golang.org/grpc/credentials/insecure" + + "github.com/argoproj/argo-workflows/v3/pkg/apiclient/artifact" + wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/util/logging" +) + +const defaultConnectionTimeoutSeconds = int32(5) + +// Driver implements the ArtifactDriver interface by making gRPC calls to a plugin service +type Driver struct { + pluginName wfv1.ArtifactPluginName + conn *grpc.ClientConn + client artifact.ArtifactServiceClient +} + +// NewDriver creates a new plugin artifact driver +func NewDriver(ctx context.Context, pluginName wfv1.ArtifactPluginName, socketPath string, connectionTimeoutSeconds int32) (*Driver, error) { + // Check for the unix socket, retrying for up to a minute if it doesn't exist immediately + logger := logging.RequireLoggerFromContext(ctx) + + // Try for up to 120 seconds, checking once per second + const maxRetries = 120 + var info os.FileInfo + var statErr error + var socketExists bool + + for retry := 0; retry < maxRetries; retry++ { + info, statErr = os.Stat(socketPath) + if statErr == nil { + socketExists = true + break + } + + if !os.IsNotExist(statErr) { + // If error is not due to missing file, fail immediately + return nil, fmt.Errorf("plugin %s cannot stat unix socket at %q: %w", pluginName, socketPath, statErr) + } + + // Socket doesn't exist yet, log at debug level and retry + logger.WithFields(logging.Fields{ + "pluginName": pluginName, + "socketPath": socketPath, + "retry": retry, + "maxRetries": maxRetries, + }).Debug(ctx, "plugin socket not found, retrying in 1s") + + // Use context-aware sleep + select { + case <-time.After(time.Second): + // Continue to next iteration + case <-ctx.Done(): + return nil, fmt.Errorf("plugin %s context cancelled while waiting for socket at %q: %w", pluginName, socketPath, ctx.Err()) + } + } + + // If socket still doesn't exist after all retries, fail with error + if !socketExists { + return nil, fmt.Errorf("plugin %s expected unix socket at %q but it does not exist after waiting for %d seconds", pluginName, socketPath, maxRetries) + } + + if (info.Mode() & os.ModeSocket) == 0 { + logger.WithFields(logging.Fields{ + "pluginName": pluginName, + "socketPath": socketPath, + "mode": info.Mode(), + }).Warn(ctx, "plugin socket file exists but is not a unix socket") + } + logger.WithFields(logging.Fields{ + "pluginName": pluginName, + "socketPath": socketPath, + "mode": info.Mode(), + }).Info(ctx, "plugin socket file exists and is a unix socket") + + conn, err := grpc.NewClient( + "unix://"+socketPath, + grpc.WithTransportCredentials(insecure.NewCredentials()), + grpc.WithContextDialer(func(ctx context.Context, addr string) (net.Conn, error) { + // Strip unix:// prefix if present + if len(addr) > 7 && addr[:7] == "unix://" { + addr = addr[7:] + } + return net.DialTimeout("unix", addr, time.Duration(connectionTimeoutSeconds)*time.Second) + }), + ) + if err != nil { + return nil, fmt.Errorf("failed to dial plugin %s at %q: %w", pluginName, socketPath, err) + } + + driver := &Driver{ + pluginName: pluginName, + conn: conn, + client: artifact.NewArtifactServiceClient(conn), + } + + // Verify the connection by checking the connection state + if connectionTimeoutSeconds == 0 { + connectionTimeoutSeconds = defaultConnectionTimeoutSeconds + } + ctx, cancel := context.WithTimeout(ctx, time.Duration(connectionTimeoutSeconds)*time.Second) + defer cancel() + + conn.Connect() + + // Wait for the connection to be ready within the timeout. + if !conn.WaitForStateChange(ctx, connectivity.Idle) { + _ = conn.Close() + return nil, fmt.Errorf("timeout waiting for plugin %s connection to become active (socket=%q)", pluginName, socketPath) + } + + logger.Info(ctx, fmt.Sprintf("plugin %s: connected successfully to %q", pluginName, socketPath)) + return driver, nil +} + +// Close closes the gRPC connection +func (d *Driver) Close() error { + if d.conn != nil { + return d.conn.Close() + } + return nil +} + +// Load implements ArtifactDriver.Load by calling the plugin service +func (d *Driver) Load(ctx context.Context, inputArtifact *wfv1.Artifact, path string) error { + grpcArtifact := convertToGRPC(inputArtifact) + resp, err := d.client.Load(ctx, &artifact.LoadArtifactRequest{ + InputArtifact: grpcArtifact, + Path: path, + }) + if err != nil { + return fmt.Errorf("plugin %s load failed: %w", d.pluginName, err) + } + if !resp.Success { + return fmt.Errorf("plugin %s load failed: %s", d.pluginName, resp.Error) + } + return nil +} + +// OpenStream implements ArtifactDriver.OpenStream by calling the plugin service +func (d *Driver) OpenStream(ctx context.Context, a *wfv1.Artifact) (io.ReadCloser, error) { + grpcArtifact := convertToGRPC(a) + stream, err := d.client.OpenStream(ctx, &artifact.OpenStreamRequest{ + Artifact: grpcArtifact, + }) + if err != nil { + return nil, fmt.Errorf("plugin %s open stream failed: %w", d.pluginName, err) + } + + reader, writer := io.Pipe() + + go func() { + defer writer.Close() + for { + resp, err := stream.Recv() + if err == io.EOF { + break + } + if err != nil { + writer.CloseWithError(fmt.Errorf("plugin %s stream receive failed: %w", d.pluginName, err)) + return + } + if resp.Error != "" { + writer.CloseWithError(fmt.Errorf("plugin %s stream error: %s", d.pluginName, resp.Error)) + return + } + if resp.IsEnd { + break + } + if len(resp.Data) > 0 { + if _, writeErr := writer.Write(resp.Data); writeErr != nil { + writer.CloseWithError(fmt.Errorf("plugin %s stream write failed: %w", d.pluginName, writeErr)) + return + } + } + } + }() + + return reader, nil +} + +// Save implements ArtifactDriver.Save by calling the plugin service +func (d *Driver) Save(ctx context.Context, path string, outputArtifact *wfv1.Artifact) error { + grpcArtifact := convertToGRPC(outputArtifact) + resp, err := d.client.Save(ctx, &artifact.SaveArtifactRequest{ + Path: path, + OutputArtifact: grpcArtifact, + }) + if err != nil { + return fmt.Errorf("plugin %s save failed: %w", d.pluginName, err) + } + if !resp.Success { + return fmt.Errorf("plugin %s save failed: %s", d.pluginName, resp.Error) + } + return nil +} + +// Delete implements ArtifactDriver.Delete by calling the plugin service +func (d *Driver) Delete(ctx context.Context, artifactRef *wfv1.Artifact) error { + grpcArtifact := convertToGRPC(artifactRef) + resp, err := d.client.Delete(ctx, &artifact.DeleteArtifactRequest{ + Artifact: grpcArtifact, + }) + if err != nil { + return fmt.Errorf("plugin %s delete failed: %w", d.pluginName, err) + } + if !resp.Success { + return fmt.Errorf("plugin %s delete failed: %s", d.pluginName, resp.Error) + } + return nil +} + +// ListObjects implements ArtifactDriver.ListObjects by calling the plugin service +func (d *Driver) ListObjects(ctx context.Context, artifactRef *wfv1.Artifact) ([]string, error) { + grpcArtifact := convertToGRPC(artifactRef) + resp, err := d.client.ListObjects(ctx, &artifact.ListObjectsRequest{ + Artifact: grpcArtifact, + }) + if err != nil { + return nil, fmt.Errorf("plugin %s list objects failed: %w", d.pluginName, err) + } + if resp.Error != "" { + return nil, fmt.Errorf("plugin %s list objects failed: %s", d.pluginName, resp.Error) + } + return resp.Objects, nil +} + +// IsDirectory implements ArtifactDriver.IsDirectory by calling the plugin service +func (d *Driver) IsDirectory(ctx context.Context, artifactRef *wfv1.Artifact) (bool, error) { + grpcArtifact := convertToGRPC(artifactRef) + resp, err := d.client.IsDirectory(ctx, &artifact.IsDirectoryRequest{ + Artifact: grpcArtifact, + }) + if err != nil { + return false, fmt.Errorf("plugin %s is directory check failed: %w", d.pluginName, err) + } + if resp.Error != "" { + return false, fmt.Errorf("plugin %s is directory check failed: %s", d.pluginName, resp.Error) + } + return resp.IsDirectory, nil +} + +// convertToGRPC converts v1alpha1.Artifact to gRPC Artifact +func convertToGRPC(a *wfv1.Artifact) *artifact.Artifact { + if a == nil { + return nil + } + + grpcArtifact := &artifact.Artifact{ + Name: a.Name, + Path: a.Path, + From: a.From, + Optional: a.Optional, + SubPath: a.SubPath, + RecurseMode: a.RecurseMode, + FromExpression: a.FromExpression, + Deleted: a.Deleted, + } + + // Handle pointer types + if a.Mode != nil { + grpcArtifact.Mode = *a.Mode + + } + + if a.Plugin != nil { + grpcArtifact.Plugin = &artifact.PluginArtifact{ + Name: string(a.Plugin.Name), + Configuration: a.Plugin.Configuration, + ConnectionTimeoutSeconds: a.Plugin.ConnectionTimeoutSeconds, + Key: a.Plugin.Key, + } + } + + return grpcArtifact +} diff --git a/workflow/artifacts/plugin/plugin_test.go b/workflow/artifacts/plugin/plugin_test.go new file mode 100644 index 000000000000..26d6261c4ad1 --- /dev/null +++ b/workflow/artifacts/plugin/plugin_test.go @@ -0,0 +1,101 @@ +package plugin + +import ( + "context" + "os" + "path/filepath" + "testing" + "time" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" + "github.com/argoproj/argo-workflows/v3/util/logging" +) + +func TestConvertToGRPC(t *testing.T) { + tests := []struct { + name string + artifact *wfv1.Artifact + expectPlugin bool + expectedPluginName string + expectedConfig string + expectedKey string + }{ + { + name: "nil artifact", + artifact: nil, + expectPlugin: false, + }, + { + name: "basic artifact", + artifact: &wfv1.Artifact{ + Name: "test-artifact", + Path: "/tmp/test", + }, + expectPlugin: false, + }, + { + name: "plugin artifact", + artifact: &wfv1.Artifact{ + Name: "test-artifact", + Path: "/tmp/test", + ArtifactLocation: wfv1.ArtifactLocation{ + Plugin: &wfv1.PluginArtifact{ + Name: "test-plugin", + Configuration: "config: value", + Key: "test-key", + }, + }, + }, + expectPlugin: true, + expectedPluginName: "test-plugin", + expectedConfig: "config: value", + expectedKey: "test-key", + }, + } + + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + result := convertToGRPC(tt.artifact) + + if tt.artifact == nil { + assert.Nil(t, result) + return + } + + require.NotNil(t, result) + assert.Equal(t, tt.artifact.Name, result.Name) + assert.Equal(t, tt.artifact.Path, result.Path) + + if tt.expectPlugin { + require.NotNil(t, result.Plugin) + assert.Equal(t, tt.expectedPluginName, result.Plugin.Name) + assert.Equal(t, tt.expectedConfig, result.Plugin.Configuration) + assert.Equal(t, tt.expectedKey, result.Plugin.Key) + } else { + if result.Plugin != nil { + assert.Nil(t, result.Plugin) + } + } + }) + } +} + +func TestNewDriver(t *testing.T) { + // This test would require a mock gRPC server to be running + // For now, we'll just test that the function returns an error for invalid socket paths + path := filepath.Join(t.TempDir(), "nonexistent", "socket") + err := os.MkdirAll(filepath.Dir(path), 0755) + require.NoError(t, err) + + // Use a context with timeout to avoid waiting the full 120 seconds + ctx := logging.TestContext(t.Context()) + ctx, cancel := context.WithTimeout(ctx, 2*time.Second) + defer cancel() + + _, err = NewDriver(ctx, "test-plugin", path, 1) + require.Error(t, err) + assert.Contains(t, err.Error(), "context cancelled while waiting for socket") +} diff --git a/workflow/common/common.go b/workflow/common/common.go index 8d5e6596a329..a3410d8fc4c5 100644 --- a/workflow/common/common.go +++ b/workflow/common/common.go @@ -1,6 +1,8 @@ package common import ( + "strings" + "k8s.io/apimachinery/pkg/apis/meta/v1/unstructured" "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow" @@ -8,9 +10,11 @@ import ( const ( // Container names used in the workflow pod - MainContainerName = "main" - InitContainerName = "init" - WaitContainerName = "wait" + MainContainerName = "main" + InitContainerName = "init" + WaitContainerName = "wait" + ArtifactPluginSidecarPrefix = "artifact-plugin-" + ArtifactPluginInitPrefix = InitContainerName + "-artifact-" // AnnotationKeyDefaultContainer is the annotation that specify container that will be used by default in case of kubectl commands for example AnnotationKeyDefaultContainer = "kubectl.kubernetes.io/default-container" @@ -136,6 +140,8 @@ const ( // EnvVarArtifactGCPodHash is applied as a Label on the WorkflowTaskSets read by the Artifact GC Pod, so that the Pod can find them EnvVarArtifactGCPodHash = "ARGO_ARTIFACT_POD_NAME" + // EnvVarArtifactPluginNames is the env var for artifact GC pods containing the names of the artifact plugins + EnvVarArtifactPluginNames = "ARGO_ARTIFACT_PLUGIN_NAMES" // EnvVarPodName contains the name of the pod (currently unused) EnvVarPodName = "ARGO_POD_NAME" // EnvVarPodUID is the workflow's UID @@ -287,3 +293,15 @@ func UnstructuredHasCompletedLabel(obj interface{}) bool { } return false } + +func IsArtifactPluginSidecar(containerName string) bool { + return strings.HasPrefix(containerName, ArtifactPluginSidecarPrefix) +} + +func IsArgoSidecar(containerName string) bool { + return containerName == WaitContainerName || IsArtifactPluginSidecar(containerName) +} + +func IsArtifactPluginInit(containerName string) bool { + return strings.HasPrefix(containerName, ArtifactPluginInitPrefix) +} diff --git a/workflow/controller/artifact_gc.go b/workflow/controller/artifact_gc.go index 3ac1efadd315..1626b2305c6a 100644 --- a/workflow/controller/artifact_gc.go +++ b/workflow/controller/artifact_gc.go @@ -6,6 +6,8 @@ import ( "hash/fnv" "slices" "sort" + "strings" + "time" "golang.org/x/exp/maps" corev1 "k8s.io/api/core/v1" @@ -415,6 +417,54 @@ func (woc *wfOperationCtx) createArtifactGCPod(ctx context.Context, strategy wfv volumes, volumeMounts := createSecretVolumesAndMountsFromArtifactLocations(artifactLocations) + pluginNames := make(map[wfv1.ArtifactPluginName]bool, 0) + for _, artifactLocation := range artifactLocations { + if artifactLocation != nil && artifactLocation.Plugin != nil && artifactLocation.Plugin.Name != "" { + pluginNames[artifactLocation.Plugin.Name] = true + } + } + woc.log.WithFields(logging.Fields{"pluginNames": pluginNames}).Info(ctx, "artifact GC plugin names") + drivers, err := woc.controller.Config.GetArtifactDrivers(maps.Keys(pluginNames)) + if err != nil { + return nil, err + } + initContainers := make([]corev1.Container, 0) + artifactDriverTmpl := wfv1.Template{ + Name: "artifact-driver", + } + + // If we want to run the sidecars, we need a copy of argoexec, + // so we run the standard init container to copy it into the + // /var/run/argo volume + if len(drivers) > 0 { + initCtr := woc.standardInitContainer(ctx, &artifactDriverTmpl) + initCtr.VolumeMounts = []corev1.VolumeMount{volumeMountVarArgo} + // Required for the init container to work + initCtr.Env = append(initCtr.Env, corev1.EnvVar{Name: common.EnvVarTemplate, Value: "{}"}) + initCtr.Env = append(initCtr.Env, corev1.EnvVar{Name: common.EnvVarDeadline, Value: time.Now().Format(time.RFC3339)}) + + initContainers = append(initContainers, *initCtr) + volumes = append(volumes, volumeVarArgo, volumeTmpDir) + volumeMounts = append(volumeMounts, volumeMountVarArgo) + } + artifactPluginSidecars := make([]corev1.Container, len(drivers)) + + for i, driver := range drivers { + woc.log.WithFields(logging.Fields{"driver": driver}).Info(ctx, "artifact GC driver") + volumes = append(volumes, driver.Name.Volume()) + volumeMounts = append(volumeMounts, driver.Name.VolumeMount()) + ctr, err := woc.artifactSidecarGCContainer(ctx, &artifactDriverTmpl, driver) + if err != nil { + return nil, err + } + ctr.VolumeMounts = append(ctr.VolumeMounts, volumeMountVarArgo) + artifactPluginSidecars[i] = *ctr + } + artifactPluginSidecarNames := make([]string, len(artifactPluginSidecars)) + for i, sidecar := range artifactPluginSidecars { + artifactPluginSidecarNames[i] = sidecar.Name + } + pod := &corev1.Pod{ ObjectMeta: metav1.ObjectMeta{ Name: podName, @@ -430,35 +480,36 @@ func (woc *wfOperationCtx) createArtifactGCPod(ctx context.Context, strategy wfv OwnerReferences: ownerReferences, }, Spec: corev1.PodSpec{ - Volumes: volumes, + Volumes: volumes, + SecurityContext: common.MinimalPodSC(), - Containers: []corev1.Container{ - { - Name: common.MainContainerName, - Image: woc.controller.executorImage(), - ImagePullPolicy: woc.controller.executorImagePullPolicy(), - Args: append([]string{"artifact", "delete"}, woc.getExecutorLogOpts(ctx)...), - Env: []corev1.EnvVar{ - {Name: common.EnvVarArtifactGCPodHash, Value: woc.artifactGCPodLabel(podName)}, + InitContainers: initContainers, + Containers: append(artifactPluginSidecars, corev1.Container{ + Name: common.MainContainerName, + Image: woc.controller.executorImage(), + ImagePullPolicy: woc.controller.executorImagePullPolicy(), + Args: append([]string{"artifact", "delete"}, woc.getExecutorLogOpts(ctx)...), + Env: []corev1.EnvVar{ + {Name: common.EnvVarArtifactGCPodHash, Value: woc.artifactGCPodLabel(podName)}, + {Name: common.EnvVarArtifactPluginNames, Value: strings.Join(artifactPluginSidecarNames, ",")}, + }, + // if this pod is breached by an attacker we: + // * prevent installation of any new packages + // * modification of the file-system + SecurityContext: common.MinimalCtrSC(), + // if this pod is breached by an attacker these limits prevent excessive CPU and memory usage + Resources: corev1.ResourceRequirements{ + Limits: map[corev1.ResourceName]resource.Quantity{ + "cpu": resource.MustParse("100m"), + "memory": resource.MustParse("64Mi"), }, - // if this pod is breached by an attacker we: - // * prevent installation of any new packages - // * modification of the file-system - SecurityContext: common.MinimalCtrSC(), - // if this pod is breached by an attacker these limits prevent excessive CPU and memory usage - Resources: corev1.ResourceRequirements{ - Limits: map[corev1.ResourceName]resource.Quantity{ - "cpu": resource.MustParse("100m"), - "memory": resource.MustParse("64Mi"), - }, - Requests: map[corev1.ResourceName]resource.Quantity{ - "cpu": resource.MustParse("50m"), - "memory": resource.MustParse("32Mi"), - }, + Requests: map[corev1.ResourceName]resource.Quantity{ + "cpu": resource.MustParse("50m"), + "memory": resource.MustParse("32Mi"), }, - VolumeMounts: volumeMounts, }, - }, + VolumeMounts: volumeMounts, + }), AutomountServiceAccountToken: ptr.To(true), RestartPolicy: corev1.RestartPolicyNever, }, @@ -487,7 +538,7 @@ func (woc *wfOperationCtx) createArtifactGCPod(ctx context.Context, strategy wfv pod.Labels[common.EnvVarInstanceID] = v } - _, err := woc.controller.kubeclientset.CoreV1().Pods(woc.wf.Namespace).Create(ctx, pod, metav1.CreateOptions{}) + _, err = woc.controller.kubeclientset.CoreV1().Pods(woc.wf.Namespace).Create(ctx, pod, metav1.CreateOptions{}) if err != nil { if apierr.IsAlreadyExists(err) { diff --git a/workflow/controller/artifact_gc_test.go b/workflow/controller/artifact_gc_test.go index 760937264055..3c91e4ee91ad 100644 --- a/workflow/controller/artifact_gc_test.go +++ b/workflow/controller/artifact_gc_test.go @@ -10,8 +10,10 @@ import ( corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "github.com/argoproj/argo-workflows/v3/config" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" "github.com/argoproj/argo-workflows/v3/util/logging" + "github.com/argoproj/argo-workflows/v3/workflow/common" ) var artgcWorkflow = `apiVersion: argoproj.io/v1alpha1 @@ -723,3 +725,197 @@ func TestWorkflowHasArtifactGC(t *testing.T) { } } + +func TestArtifactGCPodWithPlugins(t *testing.T) { + ctx := logging.TestContext(t.Context()) + + // Create a workflow with plugin artifacts + wf := &wfv1.Workflow{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-artgc-plugins", + Namespace: "default", + Labels: map[string]string{ + common.LabelKeyCompleted: "true", + }, + }, + Spec: wfv1.WorkflowSpec{ + Entrypoint: "test-template", + Templates: []wfv1.Template{ + { + Name: "test-template", + Container: &corev1.Container{ + Image: "hello-world", + }, + Outputs: wfv1.Outputs{ + Artifacts: []wfv1.Artifact{ + { + Name: "plugin-artifact-1", + Path: "/tmp/output1.txt", + ArtifactLocation: wfv1.ArtifactLocation{ + Plugin: &wfv1.PluginArtifact{ + Name: "test-plugin", + }, + }, + ArtifactGC: &wfv1.ArtifactGC{ + Strategy: wfv1.ArtifactGCOnWorkflowCompletion, + }, + }, + { + Name: "plugin-artifact-2", + Path: "/tmp/output2.txt", + ArtifactLocation: wfv1.ArtifactLocation{ + Plugin: &wfv1.PluginArtifact{ + Name: "another-plugin", + }, + }, + ArtifactGC: &wfv1.ArtifactGC{ + Strategy: wfv1.ArtifactGCOnWorkflowCompletion, + }, + }, + }, + }, + }, + }, + }, + Status: wfv1.WorkflowStatus{ + Nodes: map[string]wfv1.NodeStatus{ + "test-node-id": { + ID: "test-node-id", + Type: wfv1.NodeTypePod, + TemplateName: "test-template", + Outputs: &wfv1.Outputs{ + Artifacts: []wfv1.Artifact{ + { + Name: "plugin-artifact-1", + Path: "/tmp/output1.txt", + ArtifactLocation: wfv1.ArtifactLocation{ + Plugin: &wfv1.PluginArtifact{ + Name: "test-plugin", + }, + }, + ArtifactGC: &wfv1.ArtifactGC{ + Strategy: wfv1.ArtifactGCOnWorkflowCompletion, + }, + }, + { + Name: "plugin-artifact-2", + Path: "/tmp/output2.txt", + ArtifactLocation: wfv1.ArtifactLocation{ + Plugin: &wfv1.PluginArtifact{ + Name: "another-plugin", + }, + }, + ArtifactGC: &wfv1.ArtifactGC{ + Strategy: wfv1.ArtifactGCOnWorkflowCompletion, + }, + }, + }, + }, + }, + }, + }, + } + + cancel, controller := newController(ctx, wf) + defer cancel() + + // Configure artifact drivers + controller.Config.ArtifactDrivers = []config.ArtifactDriver{ + { + Name: "test-plugin", + Image: "busybox", + }, + { + Name: "another-plugin", + Image: "alpine", + }, + } + controller.Config.Images = map[string]config.Image{ + "busybox": { + Entrypoint: []string{"/plugin-server"}, + }, + "alpine": { + Entrypoint: []string{"/plugin-server"}, + }, + } + + woc := newWorkflowOperationCtx(ctx, wf, controller) + woc.wf.Status.ArtifactGCStatus = &wfv1.ArtGCStatus{} + + // Set up artifact repository (needed for GC to work) + repo := &wfv1.ArtifactRepository{ + S3: &wfv1.S3ArtifactRepository{ + S3Bucket: wfv1.S3Bucket{ + Bucket: "test-bucket", + }, + }, + } + setArtifactRepository(controller, repo) + woc.artifactRepository = repo + + // Process the artifact GC strategy + err := woc.processArtifactGCStrategy(ctx, wfv1.ArtifactGCOnWorkflowCompletion) + require.NoError(t, err) + + // Get the created pod + pods, err := controller.kubeclientset.CoreV1().Pods(wf.Namespace).List(ctx, metav1.ListOptions{}) + require.NoError(t, err) + require.Len(t, pods.Items, 1) + + pod := &pods.Items[0] + + // Verify the pod has the expected containers: main + 2 plugin sidecars + require.Len(t, pod.Spec.Containers, 3) + + // Find plugin sidecar containers + var testPluginSidecar, anotherPluginSidecar *corev1.Container + var mainContainer *corev1.Container + + for _, c := range pod.Spec.Containers { + switch c.Name { + case common.ArtifactPluginSidecarPrefix + "test-plugin": + testPluginSidecar = &c + case common.ArtifactPluginSidecarPrefix + "another-plugin": + anotherPluginSidecar = &c + case common.MainContainerName: + mainContainer = &c + } + } + + // Verify both plugin sidecars exist with correct images + require.NotNil(t, testPluginSidecar, "test-plugin sidecar not found") + assert.Equal(t, "busybox", testPluginSidecar.Image) + + require.NotNil(t, anotherPluginSidecar, "another-plugin sidecar not found") + assert.Equal(t, "alpine", anotherPluginSidecar.Image) + + require.NotNil(t, mainContainer, "main container not found") + + // Verify plugin volumes exist + testPluginVolume := wfv1.ArtifactPluginName("test-plugin").Volume() + anotherPluginVolume := wfv1.ArtifactPluginName("another-plugin").Volume() + assert.Contains(t, pod.Spec.Volumes, testPluginVolume) + assert.Contains(t, pod.Spec.Volumes, anotherPluginVolume) + + // Verify plugin volume mounts on main container + testPluginMount := wfv1.ArtifactPluginName("test-plugin").VolumeMount() + anotherPluginMount := wfv1.ArtifactPluginName("another-plugin").VolumeMount() + assert.Contains(t, mainContainer.VolumeMounts, testPluginMount) + assert.Contains(t, mainContainer.VolumeMounts, anotherPluginMount) + + // Verify plugin names environment variable + var pluginNamesEnv *corev1.EnvVar + for _, env := range mainContainer.Env { + if env.Name == common.EnvVarArtifactPluginNames { + pluginNamesEnv = &env + break + } + } + require.NotNil(t, pluginNamesEnv, "Plugin names env var not found") + assert.Contains(t, pluginNamesEnv.Value, common.ArtifactPluginSidecarPrefix+"test-plugin") + assert.Contains(t, pluginNamesEnv.Value, common.ArtifactPluginSidecarPrefix+"another-plugin") + + // Verify main container has artifact delete command + assert.Contains(t, mainContainer.Args, "artifact") + assert.Contains(t, mainContainer.Args, "delete") +} diff --git a/workflow/controller/controller.go b/workflow/controller/controller.go index 179477c70105..5a7ddd80a4ae 100644 --- a/workflow/controller/controller.go +++ b/workflow/controller/controller.go @@ -158,7 +158,6 @@ type WorkflowController struct { const ( workflowResyncPeriod = 20 * time.Minute workflowTemplateResyncPeriod = 20 * time.Minute - podResyncPeriod = 30 * time.Minute clusterWorkflowTemplateResyncPeriod = 20 * time.Minute workflowExistenceCheckPeriod = 1 * time.Minute workflowTaskSetResyncPeriod = 20 * time.Minute diff --git a/workflow/controller/workflowpod.go b/workflow/controller/workflowpod.go index 7d0aebaea042..a2f7cf6759e3 100644 --- a/workflow/controller/workflowpod.go +++ b/workflow/controller/workflowpod.go @@ -7,6 +7,7 @@ import ( "os" "path/filepath" "strconv" + "strings" "time" "k8s.io/apimachinery/pkg/util/strategicpatch" @@ -16,6 +17,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/utils/ptr" + "github.com/argoproj/argo-workflows/v3/config" "github.com/argoproj/argo-workflows/v3/errors" "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow" wfv1 "github.com/argoproj/argo-workflows/v3/pkg/apis/workflow/v1alpha1" @@ -128,7 +130,8 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin woc.markNodePhase(ctx, nodeName, wfv1.NodeFailed, fmt.Sprintf("workflow shutdown with strategy: %s", woc.GetShutdownStrategy())) return nil, nil } - + log := woc.log.WithFields(logging.Fields{"nodeName": nodeName, "nodeID": nodeID}) + ctx = logging.WithLogger(ctx, log) tmpl = tmpl.DeepCopy() wfSpec := woc.execWf.Spec.DeepCopy() @@ -268,10 +271,13 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin pod.Annotations[common.AnnotationKeyPodGCStrategy] = fmt.Sprintf("%s/%s", podGC.GetStrategy(), woc.getPodGCDelay(ctx, podGC)) } - // Add init container only if it needs input artifacts. This is also true for + // Add init containers only if it needs input artifacts. This is also true for // script templates (which needs to populate the script) - initCtr := woc.newInitContainer(ctx, tmpl) - pod.Spec.InitContainers = []apiv1.Container{initCtr} + initContainers, err := woc.newInitContainers(ctx, tmpl) + if err != nil { + return nil, err + } + pod.Spec.InitContainers = initContainers woc.addSchedulingConstraints(ctx, pod, wfSpec, tmpl, nodeName) woc.addMetadata(pod, tmpl) @@ -281,14 +287,14 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin if p, ok := wfv1.ParseProgress(x); ok { node, err := woc.wf.Status.Nodes.Get(nodeID) if err != nil { - woc.log.WithField("nodeID", nodeID).WithPanic().Error(ctx, "was unable to obtain node") + log.WithPanic().Error(ctx, "was unable to obtain node") } node.Progress = p woc.wf.Status.Nodes.Set(ctx, nodeID, *node) } } - err = addVolumeReferences(pod, woc.volumes, tmpl, woc.wf.Status.PersistentVolumeClaims) + err = woc.addVolumeReferences(ctx, pod, woc.volumes, tmpl, woc.wf.Status.PersistentVolumeClaims) if err != nil { return nil, err } @@ -305,8 +311,11 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin // addInitContainers, addSidecars and addOutputArtifactsVolumes should be called after all // volumes have been manipulated in the main container since volumeMounts are mirrored addInitContainers(ctx, pod, tmpl) - addSidecars(ctx, pod, tmpl) - addOutputArtifactsVolumes(ctx, pod, tmpl) + err = woc.addSidecars(ctx, pod, tmpl, &woc.controller.Config) + if err != nil { + return nil, err + } + addOutputArtifactsVolumes(pod, tmpl) for i, c := range pod.Spec.InitContainers { c.VolumeMounts = append(c.VolumeMounts, volumeMountVarArgo) @@ -402,7 +411,7 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin } for i, c := range pod.Spec.Containers { - if c.Name != common.WaitContainerName { + if !common.IsArgoSidecar(c.Name) { // https://kubernetes.io/docs/tasks/inject-data-application/define-command-argument-container/#notes if len(c.Command) == 0 { x, err := woc.controller.entrypoint.Lookup(ctx, c.Image, entrypoint.Options{ @@ -427,6 +436,15 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin SubPath: strconv.Itoa(i), }) } + // Shared tmp subpath for shared output directory + outputArtifactPlugins := len(tmpl.Outputs.Artifacts.GetPluginNames(ctx, woc.artifactRepository, wfv1.IncludeLogs, tmpl.ArchiveLocation)) > 0 + if outputArtifactPlugins && common.IsArgoSidecar(c.Name) { + c.VolumeMounts = append(c.VolumeMounts, apiv1.VolumeMount{ + Name: volumeTmpDir.Name, + MountPath: "/tmp/argo/outputs", + SubPath: "argo/outputs", + }) + } c.VolumeMounts = append(c.VolumeMounts, volumeMountVarArgo) if x := pod.Spec.TerminationGracePeriodSeconds; x != nil { c.Env = append(c.Env, apiv1.EnvVar{Name: common.EnvVarTerminationGracePeriodSeconds, Value: fmt.Sprint(*x)}) @@ -472,9 +490,9 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin if !apierr.IsAlreadyExists(err) { return nil, err } - woc.log.WithField("name", cm.Name).Info(ctx, "Configmap already exists") + log.WithField("name", cm.Name).Info(ctx, "Configmap already exists") } else { - woc.log.WithField("name", created.Name).Info(ctx, "Created configmap") + log.WithField("name", created.Name).Info(ctx, "Created configmap") } volumeConfig := apiv1.Volume{ @@ -508,7 +526,7 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin // Check if the template has exceeded its timeout duration. If it hasn't set the applicable activeDeadlineSeconds node, err := woc.wf.GetNodeByName(nodeName) if err != nil { - woc.log.WithField("nodeName", nodeName).Warn(ctx, "couldn't retrieve node, will get nil templateDeadline") + log.Warn(ctx, "couldn't retrieve node, will get nil templateDeadline") } templateDeadline, err := woc.checkTemplateTimeout(tmpl, node) if err != nil { @@ -524,7 +542,7 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin if newActiveDeadlineSeconds <= 1 { return nil, fmt.Errorf("%s exceeded its deadline", nodeName) } - woc.log.WithFields(logging.Fields{"newActiveDeadlineSeconds": newActiveDeadlineSeconds, "podNamespace": pod.Namespace, "podName": pod.Name}).Debug(ctx, "Setting new activeDeadlineSeconds") + log.WithFields(logging.Fields{"newActiveDeadlineSeconds": newActiveDeadlineSeconds, "podNamespace": pod.Namespace, "podName": pod.Name}).Debug(ctx, "Setting new activeDeadlineSeconds") pod.Spec.ActiveDeadlineSeconds = &newActiveDeadlineSeconds } @@ -532,14 +550,16 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin return nil, ErrResourceRateLimitReached } - woc.log.WithFields(logging.Fields{"nodeName": nodeName, "podName": pod.Name}).Debug(ctx, "Creating Pod") + log = log.WithField("podName", pod.Name) + ctx = logging.WithLogger(ctx, log) + log.Debug(ctx, "Creating Pod") created, err := woc.controller.kubeclientset.CoreV1().Pods(woc.wf.ObjectMeta.Namespace).Create(ctx, pod, metav1.CreateOptions{}) if err != nil { if apierr.IsAlreadyExists(err) { // workflow pod names are deterministic. We can get here if the // controller fails to persist the workflow after creating the pod. - woc.log.WithFields(logging.Fields{"nodeName": nodeName, "podName": pod.Name}).Info(ctx, "Failed pod creation: already exists") + log.Info(ctx, "Failed pod creation: already exists") // get a reference to the currently existing Pod since the created pod returned before was nil. if existing, err = woc.controller.kubeclientset.CoreV1().Pods(woc.wf.ObjectMeta.Namespace).Get(ctx, pod.Name, metav1.GetOptions{}); err == nil { return existing, nil @@ -548,10 +568,10 @@ func (woc *wfOperationCtx) createWorkflowPod(ctx context.Context, nodeName strin if errorsutil.IsTransientErr(ctx, err) { return nil, err } - woc.log.WithFields(logging.Fields{"nodeName": nodeName, "podName": pod.Name, "error": err}).Info(ctx, "Failed to create pod") + log.WithError(err).Info(ctx, "Failed to create pod") return nil, errors.InternalWrapError(err) } - woc.log.WithFields(logging.Fields{"nodeName": nodeName, "podName": created.Name}).Info(ctx, "Created pod") + log.Info(ctx, "Created pod") woc.activePods++ return created, nil } @@ -615,10 +635,82 @@ func substitutePodParams(ctx context.Context, pod *apiv1.Pod, globalParams commo return &newSpec, nil } -func (woc *wfOperationCtx) newInitContainer(ctx context.Context, tmpl *wfv1.Template) apiv1.Container { +func (woc *wfOperationCtx) standardInitContainer(ctx context.Context, tmpl *wfv1.Template) *apiv1.Container { ctr := woc.newExecContainer(common.InitContainerName, tmpl) ctr.Command = append([]string{"argoexec", "init"}, woc.getExecutorLogOpts(ctx)...) - return *ctr + return ctr +} + +func (woc *wfOperationCtx) artifactContainer(ctx context.Context, tmpl *wfv1.Template, driver config.ArtifactDriver, prefix string, execCmd []string) (*apiv1.Container, error) { + name := prefix + string(driver.Name) + ctr := woc.newExecContainer(name, tmpl) + ctr.Env = append(ctr.Env, apiv1.EnvVar{Name: common.EnvVarContainerName, Value: name}) + ctr.Image = driver.Image + x, err := woc.controller.entrypoint.Lookup(ctx, driver.Image, entrypoint.Options{ + Namespace: woc.wf.Namespace, ServiceAccountName: woc.execWf.Spec.ServiceAccountName, ImagePullSecrets: woc.execWf.Spec.ImagePullSecrets, + }) + if err != nil { + return nil, fmt.Errorf("failed to look-up entrypoint/cmd for image %q, you must either explicitly specify the command, or list the image's command in the index: https://argo-workflows.readthedocs.io/en/latest/workflow-executors/#emissary-emissary: %w", driver.Image, err) + } + + cmd := []string{common.VarRunArgoPath + "/argoexec"} + cmd = append(cmd, execCmd...) + cmd = append(cmd, woc.getExecutorLogOpts(ctx)...) + cmd = append(cmd, "--") + cmd = append(cmd, x.Entrypoint...) + cmd = append(cmd, driver.Name.SocketPath()) + ctr.Command = cmd + + return ctr, nil +} + +func (woc *wfOperationCtx) artifactSidecarGCContainer(ctx context.Context, tmpl *wfv1.Template, driver config.ArtifactDriver) (*apiv1.Container, error) { + execCmd := []string{"emissary"} + ctr, err := woc.artifactContainer(ctx, tmpl, driver, common.ArtifactPluginSidecarPrefix, execCmd) + if err != nil { + return nil, err + } + ctr.VolumeMounts = []apiv1.VolumeMount{driver.Name.VolumeMount()} + return ctr, nil +} + +func (woc *wfOperationCtx) artifactSidecarContainer(ctx context.Context, tmpl *wfv1.Template, driver config.ArtifactDriver) (*apiv1.Container, error) { + execCmd := []string{"artifact-plugin-sidecar"} + ctr, err := woc.artifactContainer(ctx, tmpl, driver, common.ArtifactPluginSidecarPrefix, execCmd) + if err != nil { + return nil, err + } + ctr.VolumeMounts = []apiv1.VolumeMount{driver.Name.VolumeMount()} + return ctr, nil +} + +func (woc *wfOperationCtx) artifactInitContainer(ctx context.Context, tmpl *wfv1.Template, driver config.ArtifactDriver) (*apiv1.Container, error) { + execCmd := []string{"artifact-plugin-init", "--plugin-name", string(driver.Name)} + return woc.artifactContainer(ctx, tmpl, driver, common.ArtifactPluginInitPrefix, execCmd) +} + +func (woc *wfOperationCtx) newInitContainers(ctx context.Context, tmpl *wfv1.Template) ([]apiv1.Container, error) { + log := logging.RequireLoggerFromContext(ctx) + plugins := tmpl.Inputs.Artifacts.GetPluginNames(ctx, woc.artifactRepository, wfv1.ExcludeLogs, tmpl.ArchiveLocation) + + log.WithFields(logging.Fields{"plugins": plugins, "pluginLen": len(plugins)}).Debug(ctx, "newInitContainers") + initContainers := make([]apiv1.Container, len(plugins)+1) + initContainers[0] = *woc.standardInitContainer(ctx, tmpl) + + drivers, err := woc.controller.Config.GetArtifactDrivers(plugins) + if err != nil { + log.WithError(err).Error(ctx, "failed to get artifact drivers") + } + for i, driver := range drivers { + log.WithFields(logging.Fields{"plugin": driver.Name, "i": i}).Debug(ctx, "adding init container") + ctr, err := woc.artifactInitContainer(ctx, tmpl, driver) + if err != nil { + return nil, err + } + + initContainers[i+1] = *ctr + } + return initContainers, nil } func (woc *wfOperationCtx) newWaitContainer(ctx context.Context, tmpl *wfv1.Template) *apiv1.Container { @@ -870,7 +962,7 @@ func (woc *wfOperationCtx) GetTemplateByBoundaryID(ctx context.Context, boundary // addVolumeReferences adds any volume mounts that a container/sidecar is referencing, to the pod.spec.volumes // These are either specified in the workflow.spec.volumes or the workflow.spec.volumeClaimTemplate section -func addVolumeReferences(pod *apiv1.Pod, vols []apiv1.Volume, tmpl *wfv1.Template, pvcs []apiv1.Volume) error { +func (woc *wfOperationCtx) addVolumeReferences(ctx context.Context, pod *apiv1.Pod, vols []apiv1.Volume, tmpl *wfv1.Template, pvcs []apiv1.Volume) error { switch tmpl.GetType() { case wfv1.TemplateTypeContainer, wfv1.TemplateTypeContainerSet, wfv1.TemplateTypeScript, wfv1.TemplateTypeResource, wfv1.TemplateTypeData: default: @@ -965,6 +1057,8 @@ func addVolumeReferences(pod *apiv1.Pod, vols []apiv1.Volume, tmpl *wfv1.Templat } } } + artifactVolumeMounts := woc.createArtifactVolumeMounts(ctx, tmpl) + pod.Spec.Volumes = append(pod.Spec.Volumes, artifactVolumeMounts...) return nil } @@ -995,9 +1089,13 @@ func (woc *wfOperationCtx) addInputArtifactsVolumes(ctx context.Context, pod *ap }, } pod.Spec.Volumes = append(pod.Spec.Volumes, artVol) - + logger := logging.RequireLoggerFromContext(ctx) + logger.Debug(ctx, "addInputArtifactsVolumes") for i, initCtr := range pod.Spec.InitContainers { - if initCtr.Name == common.InitContainerName { + logger.WithFields(logging.Fields{"name": initCtr.Name}).Debug(ctx, "checking init container volumes") + + if initCtr.Name == common.InitContainerName || common.IsArtifactPluginInit(initCtr.Name) { + logger.WithFields(logging.Fields{"name": initCtr.Name}).Debug(ctx, "adding input artifacts volume mount") volMount := apiv1.VolumeMount{ Name: artVol.Name, MountPath: common.ExecutorArtifactBaseDir, @@ -1016,7 +1114,6 @@ func (woc *wfOperationCtx) addInputArtifactsVolumes(ctx context.Context, pod *ap } pod.Spec.InitContainers[i] = initCtr - break } } @@ -1053,38 +1150,52 @@ func (woc *wfOperationCtx) addInputArtifactsVolumes(ctx context.Context, pod *ap return nil } -// addOutputArtifactsVolumes mirrors any volume mounts in the main container to the wait sidecar. +func (woc *wfOperationCtx) createArtifactVolumeMounts(ctx context.Context, tmpl *wfv1.Template) []apiv1.Volume { + artifactVolumeMounts := []apiv1.Volume{} + plugins := tmpl.Outputs.Artifacts.GetPluginNames(ctx, woc.artifactRepository, wfv1.IncludeLogs, tmpl.ArchiveLocation) + + for _, plugin := range plugins { + artifactVolumeMounts = append(artifactVolumeMounts, plugin.Volume()) + } + return artifactVolumeMounts +} + +// addOutputArtifactsVolumes mirrors any volume mounts in the main container to the wait sidecar +// and artifact-plugin sidecars. // For any output artifacts that were produced in mounted volumes (e.g. PVCs, emptyDirs), the // wait container will collect the artifacts directly from volumeMount instead of `docker cp`-ing // them to the wait sidecar. In order for this to work, we mirror all volume mounts in the main // container under a well-known path. -func addOutputArtifactsVolumes(ctx context.Context, pod *apiv1.Pod, tmpl *wfv1.Template) { +func addOutputArtifactsVolumes(pod *apiv1.Pod, tmpl *wfv1.Template) { if tmpl.GetType() == wfv1.TemplateTypeResource || tmpl.GetType() == wfv1.TemplateTypeData { return } - waitCtrIndex, err := util.FindWaitCtrIndex(pod) - if err != nil { - logging.RequireLoggerFromContext(ctx).Info(ctx, "Could not find wait container in pod spec") - return + // Collect main container volume mounts to mirror + var mainContainerMounts []apiv1.VolumeMount + for _, c := range pod.Spec.Containers { + if c.Name == common.MainContainerName { + mainContainerMounts = c.VolumeMounts + break + } } - waitCtr := &pod.Spec.Containers[waitCtrIndex] - for _, c := range pod.Spec.Containers { - if c.Name != common.MainContainerName { + // Mirror main container mounts to wait container and plugin sidecar containers + for i, c := range pod.Spec.Containers { + if !common.IsArgoSidecar(c.Name) { continue } - for _, mnt := range c.VolumeMounts { + for _, mnt := range mainContainerMounts { if util.IsWindowsUNCPath(mnt.MountPath, tmpl) { continue } mnt.MountPath = filepath.Join(common.ExecutorMainFilesystemDir, mnt.MountPath) // ReadOnly is needed to be false for overlapping volume mounts mnt.ReadOnly = false - waitCtr.VolumeMounts = append(waitCtr.VolumeMounts, mnt) + c.VolumeMounts = append(c.VolumeMounts, mnt) } + pod.Spec.Containers[i] = c } - pod.Spec.Containers[waitCtrIndex] = *waitCtr } // addArchiveLocation conditionally updates the template with the default artifact repository @@ -1225,7 +1336,7 @@ func addInitContainers(ctx context.Context, pod *apiv1.Pod, tmpl *wfv1.Template) // addSidecars adds all sidecars to the pod spec of the step. // Optionally volume mounts from the main container to the sidecar -func addSidecars(ctx context.Context, pod *apiv1.Pod, tmpl *wfv1.Template) { +func (woc *wfOperationCtx) addSidecars(ctx context.Context, pod *apiv1.Pod, tmpl *wfv1.Template, config *config.Config) error { mainCtr := findMainContainer(pod) for _, sidecar := range tmpl.Sidecars { logging.RequireLoggerFromContext(ctx).WithField("name", sidecar.Name).Debug(ctx, "Adding sidecar container") @@ -1234,6 +1345,39 @@ func addSidecars(ctx context.Context, pod *apiv1.Pod, tmpl *wfv1.Template) { } pod.Spec.Containers = append(pod.Spec.Containers, sidecar.Container) } + return woc.addArtifactPlugins(ctx, pod, tmpl, config) +} + +func (woc *wfOperationCtx) addArtifactPlugins(ctx context.Context, pod *apiv1.Pod, tmpl *wfv1.Template, config *config.Config) error { + plugins := tmpl.Outputs.Artifacts.GetPluginNames(ctx, woc.artifactRepository, wfv1.IncludeLogs, tmpl.ArchiveLocation) + drivers, err := config.GetArtifactDrivers(plugins) + if err != nil { + return err + } + + sidecarNames := make([]string, len(drivers)) + for i, driver := range drivers { + logging.RequireLoggerFromContext(ctx).WithField("name", driver.Name).Debug(ctx, "Adding artifact plugin") + ctr, err := woc.artifactSidecarContainer(ctx, tmpl, driver) + if err != nil { + return err + } + pod.Spec.Containers = append(pod.Spec.Containers, *ctr) + sidecarNames[i] = ctr.Name + } + + // Mount plugin volumes to wait container if it exists + waitCtrIndex, err := util.FindWaitCtrIndex(pod) + if err == nil { + waitCtr := &pod.Spec.Containers[waitCtrIndex] + for _, driver := range drivers { + waitCtr.VolumeMounts = append(waitCtr.VolumeMounts, driver.Name.VolumeMount()) + } + waitCtr.Env = append(waitCtr.Env, apiv1.EnvVar{Name: common.EnvVarArtifactPluginNames, Value: strings.Join(sidecarNames, ",")}) + pod.Spec.Containers[waitCtrIndex] = *waitCtr + } + + return nil } // createSecretVolumesAndMounts will retrieve and create Volumes and Volumemount object for Pod diff --git a/workflow/controller/workflowpod_test.go b/workflow/controller/workflowpod_test.go index 8eb2ea1ec85a..bfc0351b5d73 100644 --- a/workflow/controller/workflowpod_test.go +++ b/workflow/controller/workflowpod_test.go @@ -2138,3 +2138,310 @@ func TestMergeEnvVars(t *testing.T) { }) }) } + +func TestArtifactPluginSidecar(t *testing.T) { + t.Run("TestAddArtifactPluginSidecars", func(t *testing.T) { + ctx := logging.TestContext(t.Context()) + + tmpl := &wfv1.Template{ + Name: "test-template", + Container: &apiv1.Container{ + Image: "hello-world", + Command: []string{"echo", "hello"}, + }, + Outputs: wfv1.Outputs{ + Artifacts: []wfv1.Artifact{ + { + Name: "result", + Path: "/tmp/result.txt", + ArtifactLocation: wfv1.ArtifactLocation{ + Plugin: &wfv1.PluginArtifact{ + Name: "test-plugin", + }, + }, + }, + { + Name: "logs", + Path: "/tmp/logs.txt", + ArtifactLocation: wfv1.ArtifactLocation{ + Plugin: &wfv1.PluginArtifact{ + Name: "another-plugin", + }, + }, + }, + }, + }, + } + + pod := &apiv1.Pod{ + Spec: apiv1.PodSpec{ + Containers: []apiv1.Container{ + {Name: common.WaitContainerName, Image: "wait-image"}, + {Name: common.MainContainerName, Image: "main-image"}, + }, + Volumes: []apiv1.Volume{}, + }, + } + + cfg := &config.Config{ + ArtifactDrivers: []config.ArtifactDriver{ + { + Name: "test-plugin", + Image: "busybox", + }, + { + Name: "another-plugin", + Image: "alpine", + }, + }, + // Avoid Docker Hub image lookup by providing entrypoint + Images: map[string]config.Image{ + "busybox": { + Entrypoint: []string{"/plugin-server"}, + }, + "alpine": { + Entrypoint: []string{"/plugin-server"}, + }, + }, + } + + cancel, controller := newController(ctx) + defer cancel() + controller.Config.ArtifactDrivers = cfg.ArtifactDrivers + controller.Config.Images = cfg.Images + + wf := &wfv1.Workflow{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-workflow", + UID: "test-uid", + }, + Spec: wfv1.WorkflowSpec{ + Entrypoint: "test-template", + Templates: []wfv1.Template{*tmpl}, + }, + } + + woc := newWorkflowOperationCtx(ctx, wf, controller) + + err := woc.setExecWorkflow(ctx) + require.NoError(t, err) + + err = woc.addArtifactPlugins(ctx, pod, tmpl, cfg) + require.NoError(t, err) + + // Volumes are normally added in addOutputArtifactsVolumes + artifactVolumes := woc.createArtifactVolumeMounts(ctx, tmpl) + pod.Spec.Volumes = append(pod.Spec.Volumes, artifactVolumes...) + + assert.Len(t, pod.Spec.Containers, 4) // wait + main + 2 plugin sidecars + + // Test both plugin sidecar containers + var testPluginContainer, anotherPluginContainer *apiv1.Container + for _, c := range pod.Spec.Containers { + switch c.Name { + case common.ArtifactPluginSidecarPrefix + "test-plugin": + testPluginContainer = &c + case common.ArtifactPluginSidecarPrefix + "another-plugin": + anotherPluginContainer = &c + } + } + require.NotNil(t, testPluginContainer, "test-plugin sidecar container not found") + assert.Equal(t, "busybox", testPluginContainer.Image) + + require.NotNil(t, anotherPluginContainer, "another-plugin sidecar container not found") + assert.Equal(t, "alpine", anotherPluginContainer.Image) + + // Test both plugin volumes + testPluginVolume := wfv1.ArtifactPluginName("test-plugin").Volume() + anotherPluginVolume := wfv1.ArtifactPluginName("another-plugin").Volume() + assert.Contains(t, pod.Spec.Volumes, testPluginVolume) + assert.Contains(t, pod.Spec.Volumes, anotherPluginVolume) + + // Test wait container has both plugin volume mounts + waitContainer := &pod.Spec.Containers[0] + testPluginMount := wfv1.ArtifactPluginName("test-plugin").VolumeMount() + anotherPluginMount := wfv1.ArtifactPluginName("another-plugin").VolumeMount() + assert.Contains(t, waitContainer.VolumeMounts, testPluginMount) + assert.Contains(t, waitContainer.VolumeMounts, anotherPluginMount) + + // Test plugin names environment variable contains both plugins + var pluginNamesEnv *apiv1.EnvVar + for _, env := range waitContainer.Env { + if env.Name == common.EnvVarArtifactPluginNames { + pluginNamesEnv = &env + break + } + } + require.NotNil(t, pluginNamesEnv, "Plugin names env var not found") + assert.Contains(t, pluginNamesEnv.Value, common.ArtifactPluginSidecarPrefix+"test-plugin") + assert.Contains(t, pluginNamesEnv.Value, common.ArtifactPluginSidecarPrefix+"another-plugin") + }) + + t.Run("TestArtifactPluginInitContainers", func(t *testing.T) { + ctx := logging.TestContext(t.Context()) + + tmpl := &wfv1.Template{ + Name: "test-template", + Container: &apiv1.Container{ + Image: "hello-world", + Command: []string{"echo", "hello"}, + }, + Inputs: wfv1.Inputs{ + Artifacts: []wfv1.Artifact{ + { + Name: "input-data", + Path: "/tmp/input.txt", + ArtifactLocation: wfv1.ArtifactLocation{ + Plugin: &wfv1.PluginArtifact{ + Name: "test-plugin", + }, + }, + }, + { + Name: "config-data", + Path: "/tmp/config.json", + ArtifactLocation: wfv1.ArtifactLocation{ + Plugin: &wfv1.PluginArtifact{ + Name: "another-plugin", + }, + }, + }, + }, + }, + } + + cfg := &config.Config{ + ArtifactDrivers: []config.ArtifactDriver{ + { + Name: "test-plugin", + Image: "busybox", + }, + { + Name: "another-plugin", + Image: "alpine", + }, + }, + Images: map[string]config.Image{ + "busybox": { + Entrypoint: []string{"/plugin-server"}, + }, + "alpine": { + Entrypoint: []string{"/plugin-server"}, + }, + }, + } + + cancel, controller := newController(ctx) + defer cancel() + controller.Config.ArtifactDrivers = cfg.ArtifactDrivers + controller.Config.Images = cfg.Images + + wf := &wfv1.Workflow{ + ObjectMeta: metav1.ObjectMeta{ + Name: "test-workflow", + UID: "test-uid", + }, + Spec: wfv1.WorkflowSpec{ + Entrypoint: "test-template", + Templates: []wfv1.Template{*tmpl}, + }, + } + + woc := newWorkflowOperationCtx(ctx, wf, controller) + + // Skip workflow validation by not calling setExecWorkflow + // Test plugin init container creation directly + initContainers, err := woc.newInitContainers(ctx, tmpl) + require.NoError(t, err) + + // Should have standard init container plus 2 plugin init containers + assert.Len(t, initContainers, 3) + + // Test both plugin init containers + var testPluginInit, anotherPluginInit *apiv1.Container + for _, c := range initContainers { + switch c.Name { + case common.ArtifactPluginInitPrefix + "test-plugin": + testPluginInit = &c + case common.ArtifactPluginInitPrefix + "another-plugin": + anotherPluginInit = &c + } + } + + require.NotNil(t, testPluginInit, "test-plugin init container not found") + assert.Equal(t, "busybox", testPluginInit.Image) + assert.Contains(t, testPluginInit.Command, "artifact-plugin-init") + assert.Contains(t, testPluginInit.Command, "--plugin-name") + assert.Contains(t, testPluginInit.Command, "test-plugin") + + require.NotNil(t, anotherPluginInit, "another-plugin init container not found") + assert.Equal(t, "alpine", anotherPluginInit.Image) + assert.Contains(t, anotherPluginInit.Command, "artifact-plugin-init") + assert.Contains(t, anotherPluginInit.Command, "--plugin-name") + assert.Contains(t, anotherPluginInit.Command, "another-plugin") + + // Test addInputArtifactsVolumes directly with a mock pod + pod := &apiv1.Pod{ + Spec: apiv1.PodSpec{ + InitContainers: []apiv1.Container{ + {Name: common.InitContainerName, Image: "init-image"}, + {Name: common.ArtifactPluginInitPrefix + "test-plugin", Image: "busybox"}, + {Name: common.ArtifactPluginInitPrefix + "another-plugin", Image: "alpine"}, + }, + Containers: []apiv1.Container{ + {Name: common.MainContainerName, Image: "main-image"}, + }, + Volumes: []apiv1.Volume{}, + }, + } + + err = woc.addInputArtifactsVolumes(ctx, pod, tmpl) + require.NoError(t, err) + + // Should have input-artifacts volume + var inputArtifactsVolume *apiv1.Volume + for _, v := range pod.Spec.Volumes { + if v.Name == "input-artifacts" { + inputArtifactsVolume = &v + break + } + } + require.NotNil(t, inputArtifactsVolume, "input-artifacts volume not found") + assert.NotNil(t, inputArtifactsVolume.EmptyDir, "input-artifacts should be EmptyDir volume") + + // Both plugin init containers should have input-artifacts volume mount + var testPluginMount, anotherPluginMount *apiv1.VolumeMount + for _, vm := range pod.Spec.InitContainers[1].VolumeMounts { + if vm.Name == "input-artifacts" { + testPluginMount = &vm + break + } + } + for _, vm := range pod.Spec.InitContainers[2].VolumeMounts { + if vm.Name == "input-artifacts" { + anotherPluginMount = &vm + break + } + } + require.NotNil(t, testPluginMount, "test-plugin init container should have input-artifacts volume mount") + assert.Equal(t, "/argo/inputs/artifacts", testPluginMount.MountPath) + + require.NotNil(t, anotherPluginMount, "another-plugin init container should have input-artifacts volume mount") + assert.Equal(t, "/argo/inputs/artifacts", anotherPluginMount.MountPath) + + // Main container should have artifact path volume mounts for both artifacts + var inputDataMount, configDataMount *apiv1.VolumeMount + for _, vm := range pod.Spec.Containers[0].VolumeMounts { + if vm.Name == "input-artifacts" && vm.MountPath == "/tmp/input.txt" { + inputDataMount = &vm + } else if vm.Name == "input-artifacts" && vm.MountPath == "/tmp/config.json" { + configDataMount = &vm + } + } + require.NotNil(t, inputDataMount, "Main container should have input-data artifact path volume mount") + assert.Equal(t, "input-data", inputDataMount.SubPath) + + require.NotNil(t, configDataMount, "Main container should have config-data artifact path volume mount") + assert.Equal(t, "config-data", configDataMount.SubPath) + }) +} diff --git a/workflow/executor/emissary/emissary.go b/workflow/executor/emissary/emissary.go index 86da97021cf3..4cd12f594adf 100644 --- a/workflow/executor/emissary/emissary.go +++ b/workflow/executor/emissary/emissary.go @@ -134,10 +134,23 @@ func (e emissary) isComplete(containerNames []string) bool { } func (e emissary) Kill(ctx context.Context, containerNames []string, terminationGracePeriodDuration time.Duration) error { + logger := logging.RequireLoggerFromContext(ctx) + logger.WithFields(logging.Fields{"terminationGracePeriodDuration": terminationGracePeriodDuration, "containerNames": containerNames}).Info(ctx, "emissary: killing containers") for _, containerName := range containerNames { + // allow write-access by other users, because other containers // should delete the signal after receiving it - if err := os.WriteFile(filepath.Join(common.VarRunArgoPath, "ctr", containerName, "signal"), []byte(strconv.Itoa(int(syscall.SIGTERM))), 0o666); err != nil { //nolint:gosec + signalPath := filepath.Join(common.VarRunArgoPath, "ctr", containerName, "signal") + signalDir := filepath.Dir(signalPath) + logger.WithFields(logging.Fields{ + "containerName": containerName, + "signalPath": signalPath, + }).Debug(ctx, "Sending SIGTERM to container") + if err := os.MkdirAll(signalDir, 0o777); err != nil { + logger.WithField("signalDir", signalDir).WithError(err).Error(ctx, "failed to create signal directory") + return err + } + if err := os.WriteFile(signalPath, []byte(strconv.Itoa(int(syscall.SIGTERM))), 0o666); err != nil { //nolint:gosec return err } } @@ -150,7 +163,12 @@ func (e emissary) Kill(ctx context.Context, containerNames []string, termination for _, containerName := range containerNames { // allow write-access by other users, because other containers // should delete the signal after receiving it - if err := os.WriteFile(filepath.Join(common.VarRunArgoPath, "ctr", containerName, "signal"), []byte(strconv.Itoa(int(syscall.SIGKILL))), 0o666); err != nil { //nolint:gosec + signalPath := filepath.Join(common.VarRunArgoPath, "ctr", containerName, "signal") + logger.WithFields(logging.Fields{ + "containerName": containerName, + "signalPath": signalPath, + }).Debug(ctx, "Sending SIGKILL to container") + if err := os.WriteFile(signalPath, []byte(strconv.Itoa(int(syscall.SIGKILL))), 0o666); err != nil { //nolint:gosec return err } } diff --git a/workflow/executor/executor.go b/workflow/executor/executor.go index bb1dc1b6575a..f81c5e055f54 100644 --- a/workflow/executor/executor.go +++ b/workflow/executor/executor.go @@ -16,6 +16,7 @@ import ( "path" "path/filepath" "runtime/debug" + "slices" "strconv" "strings" "time" @@ -41,7 +42,7 @@ import ( errorsutil "github.com/argoproj/argo-workflows/v3/util/errors" "github.com/argoproj/argo-workflows/v3/util/retry" waitutil "github.com/argoproj/argo-workflows/v3/util/wait" - artifact "github.com/argoproj/argo-workflows/v3/workflow/artifacts" + "github.com/argoproj/argo-workflows/v3/workflow/artifacts" artifactcommon "github.com/argoproj/argo-workflows/v3/workflow/artifacts/common" "github.com/argoproj/argo-workflows/v3/workflow/common" executorretry "github.com/argoproj/argo-workflows/v3/workflow/executor/retry" @@ -170,12 +171,20 @@ func (we *WorkflowExecutor) HandleError(ctx context.Context) { } } -// LoadArtifacts loads artifacts from location to a container path -func (we *WorkflowExecutor) LoadArtifacts(ctx context.Context) error { +func (we *WorkflowExecutor) LoadArtifactsWithoutPlugins(ctx context.Context) error { + return we.loadArtifacts(ctx, "") +} + +func (we *WorkflowExecutor) LoadArtifactsFromPlugin(ctx context.Context, pluginName wfv1.ArtifactPluginName) error { + return we.loadArtifacts(ctx, pluginName) +} + +// loadArtifacts loads artifacts from location to a container path +// pluginName is the name of the plugin to load artifacts from, only one plugin can be used at a time +func (we *WorkflowExecutor) loadArtifacts(ctx context.Context, pluginName wfv1.ArtifactPluginName) error { logger := logging.RequireLoggerFromContext(ctx) - logger.Info(ctx, "Start loading input artifacts...") + logger.WithFields(logging.Fields{"pluginName": pluginName}).Info(ctx, "Start loading input artifacts...") for _, art := range we.Template.Inputs.Artifacts { - logger.WithField("name", art.Name).Info(ctx, "Downloading artifact") if !art.HasLocationOrKey() { @@ -194,6 +203,21 @@ func (we *WorkflowExecutor) LoadArtifacts(ctx context.Context) error { if err != nil { return fmt.Errorf("failed to load artifact '%s': %w", art.Name, err) } + switch pluginName { + // If no plugin is specified only load non-plugin artifacts + case "": + if driverArt.Plugin != nil { + logger.Info(ctx, "Skipping artifact that is from a plugin") + continue + } + // If a plugin is specified only load artifacts from that plugin + default: + if driverArt.Plugin == nil || driverArt.Plugin.Name != pluginName { + logger.WithFields(logging.Fields{"name": driverArt.Name, "plugin": driverArt.Plugin}).Info(ctx, "Skipping artifact that is not from the specified plugin") + continue + } + } + artDriver, err := we.InitDriver(ctx, driverArt) if err != nil { return err @@ -707,8 +731,8 @@ func (we *WorkflowExecutor) newDriverArt(art *wfv1.Artifact) (*wfv1.Artifact, er // InitDriver initializes an instance of an artifact driver func (we *WorkflowExecutor) InitDriver(ctx context.Context, art *wfv1.Artifact) (artifactcommon.ArtifactDriver, error) { - driver, err := artifact.NewDriver(ctx, art, we) - if err == artifact.ErrUnsupportedDriver { + driver, err := artifacts.NewDriver(ctx, art, we) + if err == artifacts.ErrUnsupportedDriver { return nil, argoerrs.Errorf(argoerrs.CodeBadRequest, "Unsupported artifact driver for %s", art.Name) } return driver, err @@ -1255,7 +1279,7 @@ func (we *WorkflowExecutor) monitorDeadline(ctx context.Context, containerNames var message string logger := logging.RequireLoggerFromContext(ctx) - logger.Info(ctx, "Starting deadline monitor") + logger.WithField("containers", containerNames).Info(ctx, "Starting deadline monitor") select { case <-ctx.Done(): logger.Info(ctx, "Deadline monitor stopped") @@ -1263,14 +1287,19 @@ func (we *WorkflowExecutor) monitorDeadline(ctx context.Context, containerNames case <-deadlineExceeded: message = "Step exceeded its deadline" } + // TODO: Handle not killing the artifact sidecars logger.Info(ctx, message) util.WriteTerminateMessage(message) + + containerNames = slices.DeleteFunc(containerNames, func(containerName string) bool { + return common.IsArtifactPluginSidecar(containerName) + }) we.killContainers(ctx, containerNames) } func (we *WorkflowExecutor) killContainers(ctx context.Context, containerNames []string) { logger := logging.RequireLoggerFromContext(ctx) - logger.Info(ctx, "Killing containers") + logger.WithField("containerNames", containerNames).Info(ctx, "Killing containers") terminationGracePeriodDuration := GetTerminationGracePeriodDuration() if err := we.RuntimeExecutor.Kill(ctx, containerNames, terminationGracePeriodDuration); err != nil { logger.WithField("containerNames", containerNames).WithError(err).Warn(ctx, "Failed to kill") diff --git a/workflow/executor/executor_test.go b/workflow/executor/executor_test.go index 3eddd86ae8f2..2dd453b1cc59 100644 --- a/workflow/executor/executor_test.go +++ b/workflow/executor/executor_test.go @@ -80,7 +80,7 @@ func TestWorkflowExecutor_LoadArtifacts(t *testing.T) { }, }, } - err := we.LoadArtifacts(ctx) + err := we.loadArtifacts(ctx, "") require.EqualError(t, err, test.error) }) } From e3dd8f70431f75f62fc5eaca19e51424a9a66a76 Mon Sep 17 00:00:00 2001 From: Alan Clucas Date: Tue, 7 Oct 2025 12:59:18 +0100 Subject: [PATCH 2/2] docs: add drivers to workflow-controller-cm Signed-off-by: Alan Clucas --- docs/workflow-controller-configmap.yaml | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/docs/workflow-controller-configmap.yaml b/docs/workflow-controller-configmap.yaml index 62eb65f303d7..de27025efd85 100644 --- a/docs/workflow-controller-configmap.yaml +++ b/docs/workflow-controller-configmap.yaml @@ -102,6 +102,14 @@ data: # uncomment following lines if you want to change navigation bar background color # navColor: red + # ArtifactDrivers are plugin drivers for artifacts which must be configured + # here and added to the argo-server manually as sidecars. + # artifactDrivers: | + # - name: my-custom-plugin + # image: quay.io/myorg/my-artifact-plugin:v1.0.0 + # - name: another-plugin + # image: docker.io/myorg/another-plugin:v2.1.0 + # artifactRepository defines the default location to be used as the artifact repository for # container artifacts. artifactRepository: |