From 5eab921eb0f537f1102bbdd6c38b4e52740a88a9 Mon Sep 17 00:00:00 2001 From: ybyang <10629930+berlinsaint@users.noreply.github.com> Date: Mon, 1 Nov 2021 01:45:29 +0800 Subject: [PATCH] feat: Add workflow logs selector support. Fixes #6910 (#7067) Signed-off-by: maybaby --- api/openapi-spec/swagger.json | 10 + cmd/argo/commands/logs.go | 11 +- cmd/argo/commands/submit.go | 2 +- docs/cli/argo_logs.md | 5 + docs/fields.md | 28 +++ examples/k8s-kubeflow-jobs.yaml | 66 +++++ pkg/apiclient/workflow/workflow.pb.go | 230 +++++++++++------- pkg/apiclient/workflow/workflow.proto | 1 + sdks/java/client/docs/WorkflowServiceApi.md | 12 +- sdks/python/client/docs/WorkflowServiceApi.md | 8 +- .../api/workflow_service_api.py | 12 + util/logs/workflow-logger.go | 17 +- 12 files changed, 301 insertions(+), 101 deletions(-) create mode 100644 examples/k8s-kubeflow-jobs.yaml diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index 25da1e3f3320..d9addbd10eba 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -3635,6 +3635,11 @@ "type": "string", "name": "grep", "in": "query" + }, + { + "type": "string", + "name": "selector", + "in": "query" } ], "responses": { @@ -4065,6 +4070,11 @@ "type": "string", "name": "grep", "in": "query" + }, + { + "type": "string", + "name": "selector", + "in": "query" } ], "responses": { diff --git a/cmd/argo/commands/logs.go b/cmd/argo/commands/logs.go index 6724ed7bb25d..2ab89e246639 100644 --- a/cmd/argo/commands/logs.go +++ b/cmd/argo/commands/logs.go @@ -24,6 +24,7 @@ func NewLogsCommand() *cobra.Command { sinceTime string tailLines int64 grep string + selector string ) logOptions := &corev1.PodLogOptions{} command := &cobra.Command{ @@ -37,6 +38,10 @@ func NewLogsCommand() *cobra.Command { argo logs my-wf --follow +# Print the logs of a workflows with a selector: + + argo logs my-wf -l app=sth + # Print the logs of single container in a pod argo logs my-wf my-pod -c my-container @@ -92,7 +97,7 @@ func NewLogsCommand() *cobra.Command { serviceClient := apiClient.NewWorkflowServiceClient() namespace := client.Namespace() - logWorkflow(ctx, serviceClient, namespace, workflow, podName, grep, logOptions) + logWorkflow(ctx, serviceClient, namespace, workflow, podName, grep, selector, logOptions) }, } command.Flags().StringVarP(&logOptions.Container, "container", "c", "main", "Print the logs of this container") @@ -102,18 +107,20 @@ func NewLogsCommand() *cobra.Command { command.Flags().StringVar(&sinceTime, "since-time", "", "Only return logs after a specific date (RFC3339). Defaults to all logs. Only one of since-time / since may be used.") command.Flags().Int64Var(&tailLines, "tail", -1, "If set, the number of lines from the end of the logs to show. If not specified, logs are shown from the creation of the container or sinceSeconds or sinceTime") command.Flags().StringVar(&grep, "grep", "", "grep for lines") + command.Flags().StringVarP(&selector, "selector", "l", "", "log selector for some pod") command.Flags().BoolVar(&logOptions.Timestamps, "timestamps", false, "Include timestamps on each line in the log output") command.Flags().BoolVar(&noColor, "no-color", false, "Disable colorized output") return command } -func logWorkflow(ctx context.Context, serviceClient workflowpkg.WorkflowServiceClient, namespace, workflow, podName, grep string, logOptions *corev1.PodLogOptions) { +func logWorkflow(ctx context.Context, serviceClient workflowpkg.WorkflowServiceClient, namespace, workflow, podName, grep, selector string, logOptions *corev1.PodLogOptions) { // logs stream, err := serviceClient.WorkflowLogs(ctx, &workflowpkg.WorkflowLogRequest{ Name: workflow, Namespace: namespace, PodName: podName, LogOptions: logOptions, + Selector: selector, Grep: grep, }) errors.CheckError(err) diff --git a/cmd/argo/commands/submit.go b/cmd/argo/commands/submit.go index 0e3cc5c21f7b..7f9e361a3e27 100644 --- a/cmd/argo/commands/submit.go +++ b/cmd/argo/commands/submit.go @@ -258,7 +258,7 @@ func unmarshalWorkflows(wfBytes []byte, strict bool) []wfv1.Workflow { func waitWatchOrLog(ctx context.Context, serviceClient workflowpkg.WorkflowServiceClient, namespace string, workflowNames []string, cliSubmitOpts cliSubmitOpts) { if cliSubmitOpts.log { for _, workflow := range workflowNames { - logWorkflow(ctx, serviceClient, namespace, workflow, "", "", &corev1.PodLogOptions{ + logWorkflow(ctx, serviceClient, namespace, workflow, "", "", "", &corev1.PodLogOptions{ Container: common.MainContainerName, Follow: true, Previous: false, diff --git a/docs/cli/argo_logs.md b/docs/cli/argo_logs.md index c45a7fb13181..5dc31be08bc6 100644 --- a/docs/cli/argo_logs.md +++ b/docs/cli/argo_logs.md @@ -17,6 +17,10 @@ argo logs WORKFLOW [POD] [flags] argo logs my-wf --follow +# Print the logs of a workflows with a selector: + + argo logs my-wf -l app=sth + # Print the logs of single container in a pod argo logs my-wf my-pod -c my-container @@ -43,6 +47,7 @@ argo logs WORKFLOW [POD] [flags] -h, --help help for logs --no-color Disable colorized output -p, --previous Specify if the previously terminated container logs should be returned. + -l, --selector string log selector for some pod --since duration Only return logs newer than a relative duration like 5s, 2m, or 3h. Defaults to all logs. Only one of since-time / since may be used. --since-time string Only return logs after a specific date (RFC3339). Defaults to all logs. Only one of since-time / since may be used. --tail int If set, the number of lines from the end of the logs to show. If not specified, logs are shown from the creation of the container or sinceSeconds or sinceTime (default -1) diff --git a/docs/fields.md b/docs/fields.md index 747f43e43b14..e22d0989f999 100644 --- a/docs/fields.md +++ b/docs/fields.md @@ -180,6 +180,8 @@ Workflow is the definition of a workflow resource - [`k8s-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-jobs.yaml) +- [`k8s-kubeflow-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-kubeflow-jobs.yaml) + - [`k8s-orchestration.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-orchestration.yaml) - [`k8s-owner-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-owner-reference.yaml) @@ -595,6 +597,8 @@ WorkflowSpec is the specification of a Workflow. - [`k8s-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-jobs.yaml) +- [`k8s-kubeflow-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-kubeflow-jobs.yaml) + - [`k8s-orchestration.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-orchestration.yaml) - [`k8s-owner-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-owner-reference.yaml) @@ -1028,6 +1032,8 @@ CronWorkflowSpec is the specification of a CronWorkflow - [`k8s-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-jobs.yaml) +- [`k8s-kubeflow-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-kubeflow-jobs.yaml) + - [`k8s-orchestration.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-orchestration.yaml) - [`k8s-owner-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-owner-reference.yaml) @@ -1417,6 +1423,8 @@ WorkflowTemplateSpec is a spec of WorkflowTemplate. - [`k8s-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-jobs.yaml) +- [`k8s-kubeflow-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-kubeflow-jobs.yaml) + - [`k8s-orchestration.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-orchestration.yaml) - [`k8s-owner-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-owner-reference.yaml) @@ -2217,6 +2225,8 @@ Outputs hold parameters, artifacts, and results from a step - [`k8s-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-jobs.yaml) +- [`k8s-kubeflow-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-kubeflow-jobs.yaml) + - [`k8s-orchestration.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-orchestration.yaml) - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-wait-wf.yaml) @@ -2467,6 +2477,8 @@ Parameter indicate a passed string parameter to a service template with an optio - [`k8s-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-jobs.yaml) +- [`k8s-kubeflow-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-kubeflow-jobs.yaml) + - [`k8s-orchestration.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-orchestration.yaml) - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-wait-wf.yaml) @@ -3110,6 +3122,8 @@ ResourceTemplate is a template subtype to manipulate kubernetes resources - [`k8s-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-jobs.yaml) +- [`k8s-kubeflow-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-kubeflow-jobs.yaml) + - [`k8s-orchestration.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-orchestration.yaml) - [`k8s-owner-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-owner-reference.yaml) @@ -3803,6 +3817,8 @@ ValueFrom describes a location in which to obtain the value to a parameter - [`k8s-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-jobs.yaml) +- [`k8s-kubeflow-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-kubeflow-jobs.yaml) + - [`k8s-orchestration.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-orchestration.yaml) - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-wait-wf.yaml) @@ -3947,6 +3963,8 @@ MetricLabel is a single label for a prometheus metric - [`http-hello-world.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/http-hello-world.yaml) +- [`k8s-kubeflow-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-kubeflow-jobs.yaml) + - [`k8s-owner-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-owner-reference.yaml) - [`k8s-patch-basic.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-patch-basic.yaml) @@ -4000,6 +4018,8 @@ _No description available_ - [`k8s-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-jobs.yaml) +- [`k8s-kubeflow-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-kubeflow-jobs.yaml) + - [`k8s-orchestration.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-orchestration.yaml) - [`pod-spec-patch-wf-tmpl.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/pod-spec-patch-wf-tmpl.yaml) @@ -4644,6 +4664,8 @@ _No description available_ - [`k8s-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-jobs.yaml) +- [`k8s-kubeflow-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-kubeflow-jobs.yaml) + - [`k8s-orchestration.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-orchestration.yaml) - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-wait-wf.yaml) @@ -4869,6 +4891,8 @@ ObjectMeta is metadata that all persisted resources must have, which includes al - [`k8s-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-jobs.yaml) +- [`k8s-kubeflow-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-kubeflow-jobs.yaml) + - [`k8s-orchestration.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-orchestration.yaml) - [`k8s-owner-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-owner-reference.yaml) @@ -6180,6 +6204,8 @@ PersistentVolumeClaimSpec describes the common attributes of storage devices and - [`k8s-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-jobs.yaml) +- [`k8s-kubeflow-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-kubeflow-jobs.yaml) + - [`k8s-orchestration.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-orchestration.yaml) - [`k8s-owner-reference.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-owner-reference.yaml) @@ -6803,6 +6829,8 @@ EnvVarSource represents a source for the value of an EnvVar. - [`k8s-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-jobs.yaml) +- [`k8s-kubeflow-jobs.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-kubeflow-jobs.yaml) + - [`k8s-orchestration.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-orchestration.yaml) - [`k8s-wait-wf.yaml`](https://github.com/argoproj/argo-workflows/blob/master/examples/k8s-wait-wf.yaml) diff --git a/examples/k8s-kubeflow-jobs.yaml b/examples/k8s-kubeflow-jobs.yaml new file mode 100644 index 000000000000..8ba1c9e8ab47 --- /dev/null +++ b/examples/k8s-kubeflow-jobs.yaml @@ -0,0 +1,66 @@ +# This example demonstrates the 'resource' template type, which provides a +# convenient way to create/update/delete any type of kubernetes resources +# in a workflow. The resource template type accepts any k8s manifest +# (including CRDs) and can perform any kubectl action against it (e.g. create, +# apply, delete, patch). +apiVersion: argoproj.io/v1alpha1 +kind: Workflow +metadata: + generateName: k8s-kubeflow-jobs- +spec: + entrypoint: tf-jobtmpl + templates: + - name: tf-jobtmpl + resource: + action: create + # successCondition and failureCondition are optional expressions which are + # evaluated upon every update of the resource. If failureCondition is ever + # evaluated to true, the step is considered failed. Likewise, if successCondition + # is ever evaluated to true the step is considered successful. It uses kubernetes + # label selection syntax and can be applied against any field of the resource + # (not just labels). Multiple AND conditions can be represented by comma + # delimited expressions. For more details, see: + # https://kubernetes.io/docs/concepts/overview/working-with-objects/labels/ + successCondition: status.succeeded = 2 + failureCondition: status.failed > 0 + # You can also create Any other distributed k8s resource here. This is an example + # that using KubeFlow TFJob. See more comment in the below. ↓ + manifest: | + apiVersion: kubeflow.org/v1 + kind: TFJob + metadata: + name: tfjob-examples + spec: + tfReplicaSpecs: + Worker: + replicas: 2 + restartPolicy: Never + template: + metadata: + # This label is important, so that you can use `argo logs -c tensorflow` to see the pod's logs. + # workflow.name is global varaibles that argo support. + # And the TFJob controller crd will automatically add worker pod with some labels ,such as + # job-role, replica-index. then you can use `argo logs -c tensorflow -l replica-index=0` to see + # work-0's podlogs. + # To see detail, please refer to: https://github.com/argoproj/argo-workflows/pull/7067 + labels: + workflows.argoproj.io/workflow: {{workflow.name}} + spec: + containers: + - name: tensorflow + image: "your image here" + # Resource templates can have output parameters extracted from fields of the + # resource. Two techniques are provided: jsonpath and a jq filter. + outputs: + parameters: + # job-name is extracted using a jsonPath expression and is equivalent to: + # `kubectl get job -o jsonpath='{.metadata.name}'` + - name: job-name + valueFrom: + jsonPath: '{.metadata.name}' + # job-obj is extracted using a jq filter and is equivalent to: + # `kubectl get job -o json | jq -c '.' + # which returns the entire job object in json format + - name: job-obj + valueFrom: + jqFilter: '.' diff --git a/pkg/apiclient/workflow/workflow.pb.go b/pkg/apiclient/workflow/workflow.pb.go index 99ae28876bcb..6253bc258375 100644 --- a/pkg/apiclient/workflow/workflow.pb.go +++ b/pkg/apiclient/workflow/workflow.pb.go @@ -722,6 +722,7 @@ type WorkflowLogRequest struct { PodName string `protobuf:"bytes,3,opt,name=podName,proto3" json:"podName,omitempty"` LogOptions *v11.PodLogOptions `protobuf:"bytes,4,opt,name=logOptions,proto3" json:"logOptions,omitempty"` Grep string `protobuf:"bytes,5,opt,name=grep,proto3" json:"grep,omitempty"` + Selector string `protobuf:"bytes,6,opt,name=selector,proto3" json:"selector,omitempty"` XXX_NoUnkeyedLiteral struct{} `json:"-"` XXX_unrecognized []byte `json:"-"` XXX_sizecache int32 `json:"-"` @@ -795,6 +796,13 @@ func (m *WorkflowLogRequest) GetGrep() string { return "" } +func (m *WorkflowLogRequest) GetSelector() string { + if m != nil { + return m.Selector + } + return "" +} + type WorkflowDeleteRequest struct { Name string `protobuf:"bytes,1,opt,name=name,proto3" json:"name,omitempty"` Namespace string `protobuf:"bytes,2,opt,name=namespace,proto3" json:"namespace,omitempty"` @@ -1280,95 +1288,96 @@ func init() { } var fileDescriptor_1f6bb75f9e833cb6 = []byte{ - // 1408 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x98, 0x4b, 0x6f, 0x1c, 0xc5, - 0x16, 0xc7, 0x55, 0xe3, 0xc4, 0xb1, 0xcb, 0x8f, 0x24, 0x75, 0x93, 0xdc, 0xb9, 0xad, 0xc4, 0x71, - 0x2a, 0x37, 0xf7, 0x3a, 0x4e, 0xdc, 0xed, 0x47, 0x80, 0x04, 0x09, 0x24, 0x12, 0x07, 0x8b, 0x30, - 0x84, 0xa8, 0x07, 0x09, 0xc1, 0x06, 0xb5, 0x7b, 0x8e, 0xdb, 0x1d, 0x4f, 0x77, 0x35, 0x55, 0x35, - 0x13, 0x99, 0x10, 0x24, 0xd8, 0xc0, 0x02, 0x89, 0x05, 0x4b, 0x36, 0x08, 0x81, 0x60, 0x81, 0x00, - 0x21, 0x21, 0x90, 0x90, 0x10, 0x4b, 0x96, 0x91, 0xd8, 0xb2, 0x40, 0x11, 0x5f, 0x80, 0x6f, 0x80, - 0xaa, 0xfa, 0xed, 0x99, 0x0c, 0x8d, 0x3d, 0x81, 0xec, 0xaa, 0xba, 0xbb, 0xea, 0xfc, 0xea, 0x7f, - 0xaa, 0xce, 0x39, 0xd5, 0xf8, 0x4c, 0xb4, 0xe5, 0x59, 0x4e, 0xe4, 0xbb, 0x6d, 0x1f, 0x42, 0x69, - 0xdd, 0x62, 0x7c, 0x6b, 0xa3, 0xcd, 0x6e, 0x65, 0x0d, 0x33, 0xe2, 0x4c, 0x32, 0x32, 0x96, 0xf6, - 0x8d, 0xe3, 0x1e, 0x63, 0x5e, 0x1b, 0xd4, 0x18, 0xcb, 0x09, 0x43, 0x26, 0x1d, 0xe9, 0xb3, 0x50, - 0xc4, 0xdf, 0x19, 0x17, 0xb6, 0x2e, 0x0a, 0xd3, 0x67, 0xea, 0x6d, 0xe0, 0xb8, 0x9b, 0x7e, 0x08, - 0x7c, 0xdb, 0x4a, 0x4c, 0x08, 0x2b, 0x00, 0xe9, 0x58, 0xdd, 0x25, 0xcb, 0x83, 0x10, 0xb8, 0x23, - 0xa1, 0x95, 0x8c, 0x7a, 0xce, 0xf3, 0xe5, 0x66, 0x67, 0xdd, 0x74, 0x59, 0x60, 0x39, 0xdc, 0x63, - 0x11, 0x67, 0x37, 0x75, 0x63, 0x21, 0x35, 0x2b, 0xf2, 0x49, 0x32, 0xc4, 0xee, 0x92, 0xd3, 0x8e, - 0x36, 0x9d, 0xde, 0xe9, 0x68, 0x0e, 0x61, 0xb9, 0x8c, 0x43, 0x1f, 0x93, 0xf4, 0xc7, 0x1a, 0x3e, - 0xfa, 0x62, 0x32, 0xd3, 0x15, 0x0e, 0x8e, 0x04, 0x1b, 0x5e, 0xed, 0x80, 0x90, 0xe4, 0x38, 0x1e, - 0x0f, 0x9d, 0x00, 0x44, 0xe4, 0xb8, 0x50, 0x47, 0xb3, 0x68, 0x6e, 0xdc, 0xce, 0x1f, 0x90, 0x0d, - 0x9c, 0x49, 0x51, 0xaf, 0xcd, 0xa2, 0xb9, 0x89, 0xe5, 0x6b, 0x66, 0x4e, 0x6f, 0xa6, 0xf4, 0xba, - 0xf1, 0x4a, 0x46, 0x6f, 0x76, 0x57, 0xcc, 0x68, 0xcb, 0x33, 0xd5, 0x02, 0xcc, 0x4c, 0xda, 0x74, - 0x01, 0x66, 0x0a, 0x62, 0x67, 0x73, 0x13, 0x8a, 0xb1, 0x1f, 0x0a, 0xe9, 0x84, 0x2e, 0x3c, 0xb3, - 0x5a, 0x1f, 0x51, 0x18, 0x97, 0x6b, 0x75, 0x64, 0x17, 0x9e, 0x12, 0x8a, 0x27, 0x05, 0xf0, 0x2e, - 0xf0, 0x55, 0xbe, 0x6d, 0x77, 0xc2, 0xfa, 0xbe, 0x59, 0x34, 0x37, 0x66, 0x97, 0x9e, 0x91, 0x97, - 0xf0, 0x94, 0xab, 0x97, 0xf7, 0x7c, 0xa4, 0xfd, 0x54, 0xdf, 0xaf, 0xa1, 0x57, 0xcc, 0x58, 0x23, - 0xb3, 0xe8, 0xa8, 0x1c, 0x51, 0x39, 0xca, 0xec, 0x2e, 0x99, 0x57, 0x8a, 0x43, 0xed, 0xf2, 0x4c, - 0xf4, 0x2b, 0x84, 0x49, 0x4a, 0xbe, 0x06, 0x32, 0xd5, 0x8f, 0xe0, 0x7d, 0x4a, 0xae, 0x44, 0x3a, - 0xdd, 0x2e, 0x6b, 0x5a, 0xdb, 0xa9, 0xe9, 0x0d, 0x8c, 0x3d, 0x90, 0x29, 0xe0, 0x88, 0x06, 0x5c, - 0xac, 0x06, 0xb8, 0x96, 0x8d, 0xb3, 0x0b, 0x73, 0x90, 0x63, 0x78, 0x74, 0xc3, 0x87, 0x76, 0x4b, - 0x68, 0x4d, 0xc6, 0xed, 0xa4, 0x47, 0x3f, 0x44, 0xf8, 0x5f, 0x29, 0x72, 0xc3, 0x17, 0xb2, 0x9a, - 0xcf, 0x9b, 0x78, 0xa2, 0xed, 0x8b, 0x0c, 0x30, 0x76, 0xfb, 0x52, 0x35, 0xc0, 0x46, 0x3e, 0xd0, - 0x2e, 0xce, 0x52, 0x40, 0x1c, 0x29, 0x21, 0x7a, 0xf8, 0xdf, 0xd9, 0x76, 0x00, 0xd1, 0x59, 0x0f, - 0xfc, 0x3d, 0x28, 0x6b, 0xe0, 0xb1, 0x00, 0x02, 0xe6, 0xbf, 0x06, 0x2d, 0x6d, 0x66, 0xcc, 0xce, - 0xfa, 0xf4, 0x63, 0x84, 0x8f, 0xe4, 0x96, 0x24, 0xdf, 0xde, 0xbd, 0x99, 0xf3, 0xf8, 0x30, 0x07, - 0x21, 0x1d, 0x2e, 0x9b, 0x1d, 0xd7, 0x05, 0x21, 0x36, 0x3a, 0xed, 0xc4, 0x5e, 0xef, 0x0b, 0xf5, - 0x75, 0xc8, 0x5a, 0xf0, 0xb4, 0x5a, 0x6f, 0x13, 0xda, 0xe0, 0x4a, 0xc6, 0x13, 0x3f, 0xf5, 0xbe, - 0xa0, 0xb7, 0xf2, 0x73, 0xaa, 0xf4, 0x08, 0x60, 0x4f, 0x98, 0xbd, 0x86, 0x47, 0xee, 0x67, 0xb8, - 0x81, 0xeb, 0xa9, 0xe1, 0x17, 0x80, 0x07, 0x7e, 0x58, 0x88, 0x11, 0x7f, 0xd9, 0x36, 0x7d, 0xaf, - 0xb0, 0xf3, 0x9a, 0x92, 0x45, 0x7f, 0xd3, 0x2a, 0x48, 0x1d, 0x1f, 0x08, 0x40, 0x08, 0xc7, 0x83, - 0x44, 0xe2, 0xb4, 0x4b, 0xef, 0x16, 0x8e, 0x6f, 0x73, 0x2f, 0xc7, 0x77, 0x48, 0x40, 0xe4, 0x08, - 0xde, 0x1f, 0x6d, 0x3a, 0x02, 0x74, 0x88, 0x1a, 0xb7, 0xe3, 0x0e, 0x99, 0xc7, 0x87, 0x58, 0x47, - 0x46, 0x1d, 0x79, 0xc3, 0xe1, 0x4e, 0x00, 0x12, 0xb8, 0xa8, 0x8f, 0xea, 0x0f, 0x7a, 0x9e, 0xd3, - 0x6b, 0xf8, 0x58, 0xb6, 0xa2, 0x8e, 0x88, 0x20, 0x6c, 0xed, 0xde, 0x61, 0xdf, 0x16, 0xe4, 0x69, - 0x30, 0x6f, 0xf7, 0xf2, 0xd4, 0xf1, 0x81, 0x88, 0xb5, 0xae, 0xab, 0x41, 0xb1, 0x28, 0x69, 0x97, - 0x3c, 0x85, 0x71, 0x9b, 0x79, 0x69, 0x58, 0xd9, 0xa7, 0xc3, 0xca, 0xa9, 0x42, 0x58, 0x31, 0x55, - 0xf2, 0x52, 0x41, 0xe4, 0x06, 0x6b, 0x35, 0xb2, 0x0f, 0xed, 0xc2, 0x20, 0x85, 0xe3, 0x71, 0x88, - 0x12, 0xc9, 0x74, 0x5b, 0x1d, 0xec, 0xec, 0xc8, 0xac, 0x42, 0x1b, 0xf6, 0xb0, 0x6d, 0x55, 0xfa, - 0x68, 0xe9, 0x29, 0xca, 0xd1, 0xb9, 0x62, 0xfa, 0x58, 0x2d, 0x0e, 0xb5, 0xcb, 0x33, 0xd1, 0x7a, - 0xee, 0xac, 0x94, 0x52, 0x44, 0x2c, 0x14, 0x40, 0x3f, 0x52, 0x0b, 0x70, 0xa4, 0xbb, 0x99, 0xbe, - 0x17, 0x0f, 0x61, 0x9c, 0x7e, 0xb7, 0xb0, 0x3f, 0x34, 0xec, 0xd5, 0x2e, 0x84, 0x5a, 0x62, 0xb9, - 0x1d, 0x65, 0x12, 0xab, 0x36, 0x59, 0xc7, 0xa3, 0x6c, 0xfd, 0x26, 0xb8, 0xf2, 0x01, 0x54, 0x0c, - 0xc9, 0xcc, 0xf4, 0x6d, 0x85, 0x93, 0x61, 0xfc, 0x83, 0x82, 0xd1, 0x27, 0xf1, 0x58, 0x83, 0x79, - 0x57, 0x43, 0xc9, 0xb7, 0xd5, 0xde, 0x77, 0x59, 0x28, 0x21, 0x94, 0x89, 0xf1, 0xb4, 0x5b, 0x3c, - 0x15, 0xb5, 0xd2, 0xa9, 0xa0, 0x1f, 0x94, 0x72, 0x74, 0x28, 0x1f, 0xaa, 0xba, 0x8c, 0xfe, 0x5e, - 0x38, 0x5c, 0xcd, 0x52, 0x76, 0x1e, 0xcc, 0x47, 0xf1, 0x24, 0x07, 0xc1, 0x3a, 0xdc, 0x85, 0x67, - 0xfd, 0xb0, 0x95, 0x2c, 0xba, 0xf4, 0xac, 0xf8, 0x4d, 0x21, 0x5c, 0x94, 0x9e, 0x11, 0x8e, 0xa7, - 0xe2, 0xa2, 0xa0, 0x1c, 0x36, 0x1a, 0x7b, 0x5f, 0x6c, 0x33, 0x9d, 0x56, 0xd8, 0x65, 0x13, 0xcb, - 0xbf, 0x1c, 0xc5, 0x07, 0xf3, 0x4c, 0xc1, 0xbb, 0xbe, 0x0b, 0xe4, 0x53, 0x84, 0xa7, 0xe3, 0xea, - 0x30, 0x7d, 0x43, 0x4e, 0xe6, 0x93, 0xf6, 0xad, 0xac, 0x8d, 0x21, 0x7a, 0x84, 0xce, 0xbd, 0xf5, - 0xf3, 0x6f, 0xef, 0xd7, 0x28, 0x3d, 0xa1, 0xab, 0xfc, 0xee, 0x92, 0x95, 0xdf, 0x14, 0x6e, 0x67, - 0xaa, 0xdf, 0x79, 0x1c, 0xcd, 0x93, 0x4f, 0x10, 0x9e, 0x58, 0x03, 0x99, 0x61, 0x1e, 0xef, 0xc5, - 0xcc, 0xab, 0xd7, 0xa1, 0x32, 0x9e, 0xd7, 0x8c, 0xff, 0x23, 0xff, 0x1d, 0xc8, 0x18, 0xb7, 0xef, - 0x28, 0xce, 0x29, 0x75, 0xa8, 0xb2, 0xa0, 0x47, 0x4e, 0xf4, 0x92, 0x16, 0x8a, 0x56, 0xe3, 0xfa, - 0xf0, 0x50, 0xd5, 0xb4, 0xf4, 0x8c, 0xc6, 0x3d, 0x49, 0x06, 0x4b, 0x4a, 0xde, 0xc0, 0xd3, 0xe5, - 0xe0, 0x5c, 0x72, 0x7c, 0xbf, 0xb0, 0x6d, 0xf4, 0x91, 0x3c, 0x8f, 0x55, 0xf4, 0x9c, 0xb6, 0x7b, - 0x86, 0x9c, 0xde, 0x69, 0x77, 0x01, 0x74, 0x2c, 0x2b, 0x5a, 0x5f, 0x44, 0x44, 0xe0, 0x89, 0x42, - 0xa0, 0x2b, 0xb9, 0xb3, 0x27, 0xfe, 0x19, 0xff, 0xe9, 0x97, 0x4e, 0x63, 0xb3, 0x67, 0xb5, 0xd9, - 0xd3, 0xe4, 0x54, 0x6a, 0x56, 0x48, 0x0e, 0x4e, 0x60, 0xf5, 0x35, 0xfa, 0x26, 0xc2, 0xd3, 0x71, - 0x96, 0x1a, 0xb4, 0xdd, 0x4b, 0xd9, 0xd6, 0x98, 0xbd, 0xff, 0x07, 0x49, 0xa2, 0x4b, 0x36, 0xc8, - 0x7c, 0xb5, 0x0d, 0xf2, 0x35, 0xc2, 0x53, 0xba, 0x50, 0xcf, 0x10, 0x66, 0x7a, 0x2d, 0x14, 0x2b, - 0xf9, 0xa1, 0x6e, 0xe6, 0x47, 0x34, 0xab, 0x65, 0xcc, 0x57, 0x61, 0xb5, 0xb8, 0xc2, 0x50, 0xa7, - 0xef, 0x7b, 0x84, 0x0f, 0xa5, 0xf7, 0x98, 0x8c, 0xfb, 0x54, 0x3f, 0xee, 0xd2, 0x5d, 0x67, 0xa8, - 0xe8, 0x17, 0x35, 0xfa, 0xb2, 0xb1, 0x50, 0x11, 0x3d, 0x26, 0x51, 0xf4, 0xdf, 0x20, 0x3c, 0x1d, - 0xdf, 0x3a, 0x06, 0xb9, 0xbd, 0x74, 0x2f, 0x19, 0x2a, 0xf9, 0xa3, 0x9a, 0x7c, 0xd1, 0x38, 0x57, - 0x99, 0x3c, 0x00, 0xc5, 0xfd, 0x1d, 0xc2, 0x07, 0x93, 0x0a, 0x38, 0x03, 0xef, 0xb3, 0x1d, 0xcb, - 0x45, 0xf2, 0x50, 0xc9, 0x1f, 0xd3, 0xe4, 0x4b, 0xc6, 0xf9, 0x4a, 0xe4, 0x22, 0x06, 0x51, 0xe8, - 0x3f, 0x20, 0x7c, 0x38, 0xbb, 0x6f, 0x65, 0xf0, 0xb4, 0x17, 0x7e, 0xe7, 0xa5, 0x6c, 0xa8, 0xf8, - 0x97, 0x34, 0xfe, 0x8a, 0x61, 0x56, 0xc2, 0x97, 0x29, 0x8a, 0x5a, 0xc0, 0x97, 0x08, 0x4f, 0xaa, - 0x1b, 0x5e, 0xc6, 0xde, 0x27, 0x8c, 0x17, 0x6e, 0x80, 0x43, 0xc5, 0xbe, 0xa0, 0xb1, 0x4d, 0xe3, - 0x6c, 0x35, 0xd5, 0x25, 0x8b, 0x14, 0xf1, 0xe7, 0x08, 0x4f, 0x34, 0x07, 0x67, 0xc8, 0xe6, 0x83, - 0xc9, 0x90, 0x2b, 0x9a, 0x77, 0xc1, 0x98, 0xab, 0xc6, 0x0b, 0xfa, 0x50, 0x7e, 0x86, 0xf0, 0xa4, - 0x2a, 0x0c, 0x07, 0x09, 0x5c, 0x28, 0x1c, 0x87, 0x0a, 0xbc, 0xa0, 0x81, 0xff, 0x4f, 0xe9, 0x60, - 0xe0, 0xb6, 0x1f, 0x6a, 0xd4, 0xd7, 0xf1, 0x81, 0xf8, 0xee, 0x26, 0xfa, 0x89, 0x9a, 0x5f, 0x2b, - 0x0d, 0x92, 0xbf, 0x4d, 0x8b, 0x67, 0xfa, 0x84, 0xb6, 0x75, 0x81, 0x2c, 0x57, 0x12, 0xe7, 0x76, - 0x52, 0x3f, 0xdf, 0xb1, 0xda, 0xcc, 0x7b, 0xa7, 0x86, 0x16, 0x11, 0x91, 0x78, 0xb2, 0x60, 0x6a, - 0x37, 0x08, 0x8b, 0x1a, 0x61, 0x9e, 0x54, 0xf3, 0x4f, 0x9b, 0x79, 0x8b, 0x88, 0x7c, 0x81, 0xf0, - 0x74, 0xb3, 0x1c, 0xef, 0x4f, 0xf6, 0x0b, 0x3d, 0x0f, 0x2a, 0xda, 0x5b, 0x9a, 0xf9, 0x2c, 0xfd, - 0x93, 0xa4, 0x9a, 0x05, 0xf9, 0xcb, 0x6b, 0x3f, 0xdd, 0x9b, 0x41, 0x77, 0xef, 0xcd, 0xa0, 0x5f, - 0xef, 0xcd, 0xa0, 0x97, 0x2f, 0x55, 0xff, 0x17, 0xbd, 0xe3, 0x9f, 0xf9, 0xfa, 0xa8, 0xfe, 0xb5, - 0xbc, 0xf2, 0x47, 0x00, 0x00, 0x00, 0xff, 0xff, 0x34, 0xa6, 0x8f, 0x98, 0x54, 0x17, 0x00, 0x00, + // 1416 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xcc, 0x98, 0x4f, 0x6f, 0xdc, 0xc4, + 0x1b, 0xc7, 0x35, 0x9b, 0x36, 0x4d, 0x26, 0x7f, 0xda, 0xce, 0xaf, 0xed, 0x6f, 0xb1, 0xda, 0x34, + 0x9d, 0x52, 0x48, 0xd3, 0xc6, 0xce, 0x26, 0x05, 0x5a, 0x24, 0x90, 0x68, 0x53, 0x22, 0xca, 0x52, + 0x2a, 0x2f, 0x12, 0x82, 0x0b, 0x72, 0xbc, 0x13, 0xc7, 0x8d, 0xed, 0x31, 0x33, 0xb3, 0x5b, 0x85, + 0x52, 0x24, 0xb8, 0xc0, 0x01, 0x89, 0x03, 0x47, 0x2e, 0x08, 0x81, 0xe0, 0x80, 0x00, 0x21, 0x21, + 0x21, 0x21, 0x21, 0x8e, 0x1c, 0x2b, 0xf5, 0xca, 0x01, 0x55, 0xbc, 0x01, 0xde, 0x01, 0x9a, 0xb1, + 0x3d, 0xb6, 0xb3, 0xdb, 0xc5, 0x24, 0x1b, 0xe8, 0x6d, 0xc6, 0xf6, 0xcc, 0xf3, 0x99, 0xef, 0x33, + 0xf3, 0x3c, 0xcf, 0x18, 0x9e, 0x89, 0x37, 0x3d, 0xcb, 0x89, 0x7d, 0x37, 0xf0, 0x49, 0x24, 0xac, + 0x5b, 0x94, 0x6d, 0xae, 0x07, 0xf4, 0x96, 0x6e, 0x98, 0x31, 0xa3, 0x82, 0xa2, 0xb1, 0xac, 0x6f, + 0x1c, 0xf7, 0x28, 0xf5, 0x02, 0x22, 0xc7, 0x58, 0x4e, 0x14, 0x51, 0xe1, 0x08, 0x9f, 0x46, 0x3c, + 0xf9, 0xce, 0xb8, 0xb0, 0x79, 0x91, 0x9b, 0x3e, 0x95, 0x6f, 0x43, 0xc7, 0xdd, 0xf0, 0x23, 0xc2, + 0xb6, 0xac, 0xd4, 0x04, 0xb7, 0x42, 0x22, 0x1c, 0xab, 0xdb, 0xb0, 0x3c, 0x12, 0x11, 0xe6, 0x08, + 0xd2, 0x4e, 0x47, 0xbd, 0xe4, 0xf9, 0x62, 0xa3, 0xb3, 0x66, 0xba, 0x34, 0xb4, 0x1c, 0xe6, 0xd1, + 0x98, 0xd1, 0x9b, 0xaa, 0xb1, 0x90, 0x99, 0xe5, 0xf9, 0x24, 0x1a, 0xb1, 0xdb, 0x70, 0x82, 0x78, + 0xc3, 0xe9, 0x9d, 0x0e, 0xe7, 0x10, 0x96, 0x4b, 0x19, 0xe9, 0x63, 0x12, 0xff, 0x52, 0x83, 0x47, + 0x5f, 0x4d, 0x67, 0xba, 0xc2, 0x88, 0x23, 0x88, 0x4d, 0xde, 0xec, 0x10, 0x2e, 0xd0, 0x71, 0x38, + 0x1e, 0x39, 0x21, 0xe1, 0xb1, 0xe3, 0x92, 0x3a, 0x98, 0x05, 0x73, 0xe3, 0x76, 0xfe, 0x00, 0xad, + 0x43, 0x2d, 0x45, 0xbd, 0x36, 0x0b, 0xe6, 0x26, 0x96, 0xae, 0x99, 0x39, 0xbd, 0x99, 0xd1, 0xab, + 0xc6, 0x1b, 0x9a, 0xde, 0xec, 0x2e, 0x9b, 0xf1, 0xa6, 0x67, 0xca, 0x05, 0x98, 0x5a, 0xda, 0x6c, + 0x01, 0x66, 0x06, 0x62, 0xeb, 0xb9, 0x11, 0x86, 0xd0, 0x8f, 0xb8, 0x70, 0x22, 0x97, 0xbc, 0xb0, + 0x52, 0x1f, 0x91, 0x18, 0x97, 0x6b, 0x75, 0x60, 0x17, 0x9e, 0x22, 0x0c, 0x27, 0x39, 0x61, 0x5d, + 0xc2, 0x56, 0xd8, 0x96, 0xdd, 0x89, 0xea, 0xfb, 0x66, 0xc1, 0xdc, 0x98, 0x5d, 0x7a, 0x86, 0x5e, + 0x83, 0x53, 0xae, 0x5a, 0xde, 0xcb, 0xb1, 0xf2, 0x53, 0x7d, 0xbf, 0x82, 0x5e, 0x36, 0x13, 0x8d, + 0xcc, 0xa2, 0xa3, 0x72, 0x44, 0xe9, 0x28, 0xb3, 0xdb, 0x30, 0xaf, 0x14, 0x87, 0xda, 0xe5, 0x99, + 0xf0, 0x77, 0x00, 0xa2, 0x8c, 0x7c, 0x95, 0x88, 0x4c, 0x3f, 0x04, 0xf7, 0x49, 0xb9, 0x52, 0xe9, + 0x54, 0xbb, 0xac, 0x69, 0x6d, 0xbb, 0xa6, 0x37, 0x20, 0xf4, 0x88, 0xc8, 0x00, 0x47, 0x14, 0xe0, + 0x62, 0x35, 0xc0, 0x55, 0x3d, 0xce, 0x2e, 0xcc, 0x81, 0x8e, 0xc1, 0xd1, 0x75, 0x9f, 0x04, 0x6d, + 0xae, 0x34, 0x19, 0xb7, 0xd3, 0x1e, 0xfe, 0x14, 0xc0, 0xff, 0x65, 0xc8, 0x4d, 0x9f, 0x8b, 0x6a, + 0x3e, 0x6f, 0xc1, 0x89, 0xc0, 0xe7, 0x1a, 0x30, 0x71, 0x7b, 0xa3, 0x1a, 0x60, 0x33, 0x1f, 0x68, + 0x17, 0x67, 0x29, 0x20, 0x8e, 0x94, 0x10, 0x3d, 0xf8, 0x7f, 0xbd, 0x1d, 0x08, 0xef, 0xac, 0x85, + 0xfe, 0x2e, 0x94, 0x35, 0xe0, 0x58, 0x48, 0x42, 0xea, 0xbf, 0x45, 0xda, 0xca, 0xcc, 0x98, 0xad, + 0xfb, 0xf8, 0x73, 0x00, 0x8f, 0xe4, 0x96, 0x04, 0xdb, 0xda, 0xb9, 0x99, 0xf3, 0xf0, 0x30, 0x23, + 0x5c, 0x38, 0x4c, 0xb4, 0x3a, 0xae, 0x4b, 0x38, 0x5f, 0xef, 0x04, 0xa9, 0xbd, 0xde, 0x17, 0xf2, + 0xeb, 0x88, 0xb6, 0xc9, 0xf3, 0x72, 0xbd, 0x2d, 0x12, 0x10, 0x57, 0x50, 0x96, 0xfa, 0xa9, 0xf7, + 0x05, 0xbe, 0x95, 0x9f, 0x53, 0xa9, 0x47, 0x48, 0x76, 0x85, 0xd9, 0x6b, 0x78, 0xe4, 0x41, 0x86, + 0x9b, 0xb0, 0x9e, 0x19, 0x7e, 0x85, 0xb0, 0xd0, 0x8f, 0x0a, 0x31, 0xe2, 0x1f, 0xdb, 0xc6, 0x1f, + 0x15, 0x76, 0x5e, 0x4b, 0xd0, 0xf8, 0x5f, 0x5a, 0x05, 0xaa, 0xc3, 0x03, 0x21, 0xe1, 0xdc, 0xf1, + 0x48, 0x2a, 0x71, 0xd6, 0xc5, 0x77, 0x0b, 0xc7, 0xb7, 0xb5, 0x9b, 0xe3, 0x3b, 0x24, 0x20, 0x74, + 0x04, 0xee, 0x8f, 0x37, 0x1c, 0x4e, 0x54, 0x88, 0x1a, 0xb7, 0x93, 0x0e, 0x9a, 0x87, 0x87, 0x68, + 0x47, 0xc4, 0x1d, 0x71, 0xc3, 0x61, 0x4e, 0x48, 0x04, 0x61, 0xbc, 0x3e, 0xaa, 0x3e, 0xe8, 0x79, + 0x8e, 0xaf, 0xc1, 0x63, 0x7a, 0x45, 0x1d, 0x1e, 0x93, 0xa8, 0xbd, 0x73, 0x87, 0xdd, 0x2b, 0xc8, + 0xd3, 0xa4, 0xde, 0xce, 0xe5, 0xa9, 0xc3, 0x03, 0x31, 0x6d, 0x5f, 0x97, 0x83, 0x12, 0x51, 0xb2, + 0x2e, 0x7a, 0x0e, 0xc2, 0x80, 0x7a, 0x59, 0x58, 0xd9, 0xa7, 0xc2, 0xca, 0xa9, 0x42, 0x58, 0x31, + 0x65, 0xf2, 0x92, 0x41, 0xe4, 0x06, 0x6d, 0x37, 0xf5, 0x87, 0x76, 0x61, 0x90, 0xc4, 0xf1, 0x18, + 0x89, 0x53, 0xc9, 0x54, 0x5b, 0x1e, 0x7a, 0x9e, 0xb9, 0x21, 0x51, 0x4a, 0xf7, 0xe5, 0xa1, 0xd7, + 0xc7, 0x69, 0x85, 0x04, 0x64, 0x17, 0x5b, 0x5a, 0xa6, 0x96, 0xb6, 0x9a, 0xa2, 0x1c, 0xb9, 0x2b, + 0xa6, 0x96, 0x95, 0xe2, 0x50, 0xbb, 0x3c, 0x13, 0xae, 0xe7, 0x8e, 0xcc, 0x28, 0x79, 0x4c, 0x23, + 0x4e, 0xf0, 0x67, 0x72, 0x01, 0x8e, 0x70, 0x37, 0xb2, 0xf7, 0xfc, 0x21, 0x8c, 0xe1, 0x1f, 0x16, + 0xf6, 0x8e, 0x82, 0xbd, 0xda, 0x25, 0x91, 0x92, 0x58, 0x6c, 0xc5, 0x5a, 0x62, 0xd9, 0x46, 0x6b, + 0x70, 0x94, 0xae, 0xdd, 0x24, 0xae, 0xd8, 0x83, 0x6a, 0x22, 0x9d, 0x19, 0xbf, 0x2f, 0x71, 0x34, + 0xc6, 0x7f, 0x28, 0x18, 0x7e, 0x16, 0x8e, 0x35, 0xa9, 0x77, 0x35, 0x12, 0x6c, 0x4b, 0x9e, 0x0b, + 0x97, 0x46, 0x82, 0x44, 0x22, 0x35, 0x9e, 0x75, 0x8b, 0x27, 0xa6, 0x56, 0x3a, 0x31, 0xf8, 0x93, + 0x52, 0xfe, 0x8e, 0xc4, 0x43, 0x55, 0xb3, 0xe1, 0x3f, 0x0b, 0x87, 0xab, 0x55, 0xca, 0xdc, 0x83, + 0xf9, 0x30, 0x9c, 0x64, 0x84, 0xd3, 0x0e, 0x73, 0xc9, 0x8b, 0x7e, 0xd4, 0x4e, 0x17, 0x5d, 0x7a, + 0x56, 0xfc, 0xa6, 0x10, 0x4a, 0x4a, 0xcf, 0x10, 0x83, 0x53, 0x49, 0xc1, 0x50, 0x0e, 0x29, 0xcd, + 0xdd, 0x2f, 0xb6, 0x95, 0x4d, 0xcb, 0xed, 0xb2, 0x89, 0xa5, 0xdf, 0x8e, 0xc2, 0x83, 0x79, 0x16, + 0x61, 0x5d, 0xdf, 0x25, 0xe8, 0x4b, 0x00, 0xa7, 0x93, 0xca, 0x31, 0x7b, 0x83, 0x4e, 0xe6, 0x93, + 0xf6, 0xad, 0xba, 0x8d, 0x21, 0x7a, 0x04, 0xcf, 0xbd, 0x77, 0xef, 0x8f, 0x8f, 0x6b, 0x18, 0x9f, + 0x50, 0x37, 0x80, 0x6e, 0xc3, 0xca, 0x6f, 0x11, 0xb7, 0xb5, 0xea, 0x77, 0x9e, 0x06, 0xf3, 0xe8, + 0x0b, 0x00, 0x27, 0x56, 0x89, 0xd0, 0x98, 0xc7, 0x7b, 0x31, 0xf3, 0xca, 0x76, 0xa8, 0x8c, 0xe7, + 0x15, 0xe3, 0x63, 0xe8, 0xd1, 0x81, 0x8c, 0x49, 0xfb, 0x8e, 0xe4, 0x9c, 0x92, 0x87, 0x4a, 0x07, + 0x3d, 0x74, 0xa2, 0x97, 0xb4, 0x50, 0xd0, 0x1a, 0xd7, 0x87, 0x87, 0x2a, 0xa7, 0xc5, 0x67, 0x14, + 0xee, 0x49, 0x34, 0x58, 0x52, 0xf4, 0x0e, 0x9c, 0x2e, 0x07, 0xe7, 0x92, 0xe3, 0xfb, 0x85, 0x6d, + 0xa3, 0x8f, 0xe4, 0x79, 0xac, 0xc2, 0xe7, 0x94, 0xdd, 0x33, 0xe8, 0xf4, 0x76, 0xbb, 0x0b, 0x44, + 0xc5, 0xb2, 0xa2, 0xf5, 0x45, 0x80, 0x38, 0x9c, 0x28, 0x04, 0xba, 0x92, 0x3b, 0x7b, 0xe2, 0x9f, + 0xf1, 0x48, 0xbf, 0x54, 0x9b, 0x98, 0x3d, 0xab, 0xcc, 0x9e, 0x46, 0xa7, 0x32, 0xb3, 0x5c, 0x30, + 0xe2, 0x84, 0x56, 0x5f, 0xa3, 0xef, 0x02, 0x38, 0x9d, 0x64, 0xa9, 0x41, 0xdb, 0xbd, 0x94, 0x6d, + 0x8d, 0xd9, 0x07, 0x7f, 0x90, 0x26, 0xba, 0x74, 0x83, 0xcc, 0x57, 0xdb, 0x20, 0xdf, 0x03, 0x38, + 0xa5, 0x8a, 0x78, 0x8d, 0x30, 0xd3, 0x6b, 0xa1, 0x58, 0xe5, 0x0f, 0x75, 0x33, 0x3f, 0xa1, 0x58, + 0x2d, 0x63, 0xbe, 0x0a, 0xab, 0xc5, 0x24, 0x86, 0x3c, 0x7d, 0x3f, 0x01, 0x78, 0x28, 0xbb, 0xe3, + 0x68, 0xee, 0x53, 0xfd, 0xb8, 0x4b, 0xf7, 0xa0, 0xa1, 0xa2, 0x5f, 0x54, 0xe8, 0x4b, 0xc6, 0x42, + 0x45, 0xf4, 0x84, 0x44, 0xd2, 0xff, 0x00, 0xe0, 0x74, 0x72, 0x23, 0x19, 0xe4, 0xf6, 0xd2, 0x9d, + 0x65, 0xa8, 0xe4, 0x4f, 0x2a, 0xf2, 0x45, 0xe3, 0x5c, 0x65, 0xf2, 0x90, 0x48, 0xee, 0x1f, 0x01, + 0x3c, 0x98, 0x56, 0xc7, 0x1a, 0xbc, 0xcf, 0x76, 0x2c, 0x17, 0xd0, 0x43, 0x25, 0x7f, 0x4a, 0x91, + 0x37, 0x8c, 0xf3, 0x95, 0xc8, 0x79, 0x02, 0x22, 0xd1, 0x7f, 0x06, 0xf0, 0xb0, 0xbe, 0x8b, 0x69, + 0x78, 0xdc, 0x0b, 0xbf, 0xfd, 0xc2, 0x36, 0x54, 0xfc, 0x4b, 0x0a, 0x7f, 0xd9, 0x30, 0x2b, 0xe1, + 0x8b, 0x0c, 0x45, 0x2e, 0xe0, 0x5b, 0x00, 0x27, 0xe5, 0xed, 0x4f, 0xb3, 0xf7, 0x09, 0xe3, 0x85, + 0xdb, 0xe1, 0x50, 0xb1, 0x2f, 0x28, 0x6c, 0xd3, 0x38, 0x5b, 0x4d, 0x75, 0x41, 0x63, 0x49, 0xfc, + 0x35, 0x80, 0x13, 0xad, 0xc1, 0x19, 0xb2, 0xb5, 0x37, 0x19, 0x72, 0x59, 0xf1, 0x2e, 0x18, 0x73, + 0xd5, 0x78, 0x89, 0x3a, 0x94, 0x5f, 0x01, 0x38, 0x29, 0x0b, 0xc3, 0x41, 0x02, 0x17, 0x0a, 0xc7, + 0xa1, 0x02, 0x2f, 0x28, 0xe0, 0xc7, 0x31, 0x1e, 0x0c, 0x1c, 0xf8, 0x91, 0x42, 0x7d, 0x1b, 0x1e, + 0x48, 0xee, 0x75, 0xbc, 0x9f, 0xa8, 0xf9, 0x95, 0xd3, 0x40, 0xf9, 0xdb, 0xac, 0x78, 0xc6, 0xcf, + 0x28, 0x5b, 0x17, 0xd0, 0x52, 0x25, 0x71, 0x6e, 0xa7, 0xf5, 0xf3, 0x1d, 0x2b, 0xa0, 0xde, 0x07, + 0x35, 0xb0, 0x08, 0x90, 0x80, 0x93, 0x05, 0x53, 0x3b, 0x41, 0x58, 0x54, 0x08, 0xf3, 0xa8, 0x9a, + 0x7f, 0x02, 0xea, 0x2d, 0x02, 0xf4, 0x0d, 0x80, 0xd3, 0xad, 0x72, 0xbc, 0x3f, 0xd9, 0x2f, 0xf4, + 0xec, 0x55, 0xb4, 0xb7, 0x14, 0xf3, 0x59, 0xfc, 0x37, 0x49, 0x55, 0x07, 0xf9, 0xcb, 0xab, 0xbf, + 0xde, 0x9f, 0x01, 0x77, 0xef, 0xcf, 0x80, 0xdf, 0xef, 0xcf, 0x80, 0xd7, 0x2f, 0x55, 0xff, 0x4f, + 0xbd, 0xed, 0x7f, 0xfa, 0xda, 0xa8, 0xfa, 0xed, 0xbc, 0xfc, 0x57, 0x00, 0x00, 0x00, 0xff, 0xff, + 0xd5, 0x18, 0x9f, 0xd1, 0x70, 0x17, 0x00, 0x00, } // Reference imports to suppress errors if they are not otherwise used. @@ -2714,6 +2723,13 @@ func (m *WorkflowLogRequest) MarshalToSizedBuffer(dAtA []byte) (int, error) { i -= len(m.XXX_unrecognized) copy(dAtA[i:], m.XXX_unrecognized) } + if len(m.Selector) > 0 { + i -= len(m.Selector) + copy(dAtA[i:], m.Selector) + i = encodeVarintWorkflow(dAtA, i, uint64(len(m.Selector))) + i-- + dAtA[i] = 0x32 + } if len(m.Grep) > 0 { i -= len(m.Grep) copy(dAtA[i:], m.Grep) @@ -3427,6 +3443,10 @@ func (m *WorkflowLogRequest) Size() (n int) { if l > 0 { n += 1 + l + sovWorkflow(uint64(l)) } + l = len(m.Selector) + if l > 0 { + n += 1 + l + sovWorkflow(uint64(l)) + } if m.XXX_unrecognized != nil { n += len(m.XXX_unrecognized) } @@ -5442,6 +5462,38 @@ func (m *WorkflowLogRequest) Unmarshal(dAtA []byte) error { } m.Grep = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex + case 6: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Selector", wireType) + } + var stringLen uint64 + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowWorkflow + } + 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 ErrInvalidLengthWorkflow + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthWorkflow + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Selector = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipWorkflow(dAtA[iNdEx:]) diff --git a/pkg/apiclient/workflow/workflow.proto b/pkg/apiclient/workflow/workflow.proto index 89555c08f836..676d5b96dd6b 100644 --- a/pkg/apiclient/workflow/workflow.proto +++ b/pkg/apiclient/workflow/workflow.proto @@ -85,6 +85,7 @@ message WorkflowLogRequest { string podName = 3; k8s.io.api.core.v1.PodLogOptions logOptions = 4; string grep = 5; + string selector = 6; } message WorkflowDeleteRequest { diff --git a/sdks/java/client/docs/WorkflowServiceApi.md b/sdks/java/client/docs/WorkflowServiceApi.md index f3643f53ef77..41cd6b1315d9 100644 --- a/sdks/java/client/docs/WorkflowServiceApi.md +++ b/sdks/java/client/docs/WorkflowServiceApi.md @@ -374,7 +374,7 @@ No authorization required # **workflowServicePodLogs** -> StreamResultOfIoArgoprojWorkflowV1alpha1LogEntry workflowServicePodLogs(namespace, name, podName, logOptionsContainer, logOptionsFollow, logOptionsPrevious, logOptionsSinceSeconds, logOptionsSinceTimeSeconds, logOptionsSinceTimeNanos, logOptionsTimestamps, logOptionsTailLines, logOptionsLimitBytes, logOptionsInsecureSkipTLSVerifyBackend, grep) +> StreamResultOfIoArgoprojWorkflowV1alpha1LogEntry workflowServicePodLogs(namespace, name, podName, logOptionsContainer, logOptionsFollow, logOptionsPrevious, logOptionsSinceSeconds, logOptionsSinceTimeSeconds, logOptionsSinceTimeNanos, logOptionsTimestamps, logOptionsTailLines, logOptionsLimitBytes, logOptionsInsecureSkipTLSVerifyBackend, grep, selector) DEPRECATED: Cannot work via HTTP if podName is an empty string. Use WorkflowLogs. @@ -407,8 +407,9 @@ public class Example { String logOptionsLimitBytes = "logOptionsLimitBytes_example"; // String | If set, the number of bytes to read from the server before terminating the log output. This may not display a complete final line of logging, and may return slightly more or slightly less than the specified limit. +optional. Boolean logOptionsInsecureSkipTLSVerifyBackend = true; // Boolean | insecureSkipTLSVerifyBackend indicates that the apiserver should not confirm the validity of the serving certificate of the backend it is connecting to. This will make the HTTPS connection between the apiserver and the backend insecure. This means the apiserver cannot verify the log data it is receiving came from the real kubelet. If the kubelet is configured to verify the apiserver's TLS credentials, it does not mean the connection to the real kubelet is vulnerable to a man in the middle attack (e.g. an attacker could not intercept the actual log data coming from the real kubelet). +optional. String grep = "grep_example"; // String | + String selector = "selector_example"; // String | try { - StreamResultOfIoArgoprojWorkflowV1alpha1LogEntry result = apiInstance.workflowServicePodLogs(namespace, name, podName, logOptionsContainer, logOptionsFollow, logOptionsPrevious, logOptionsSinceSeconds, logOptionsSinceTimeSeconds, logOptionsSinceTimeNanos, logOptionsTimestamps, logOptionsTailLines, logOptionsLimitBytes, logOptionsInsecureSkipTLSVerifyBackend, grep); + StreamResultOfIoArgoprojWorkflowV1alpha1LogEntry result = apiInstance.workflowServicePodLogs(namespace, name, podName, logOptionsContainer, logOptionsFollow, logOptionsPrevious, logOptionsSinceSeconds, logOptionsSinceTimeSeconds, logOptionsSinceTimeNanos, logOptionsTimestamps, logOptionsTailLines, logOptionsLimitBytes, logOptionsInsecureSkipTLSVerifyBackend, grep, selector); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling WorkflowServiceApi#workflowServicePodLogs"); @@ -439,6 +440,7 @@ Name | Type | Description | Notes **logOptionsLimitBytes** | **String**| If set, the number of bytes to read from the server before terminating the log output. This may not display a complete final line of logging, and may return slightly more or slightly less than the specified limit. +optional. | [optional] **logOptionsInsecureSkipTLSVerifyBackend** | **Boolean**| insecureSkipTLSVerifyBackend indicates that the apiserver should not confirm the validity of the serving certificate of the backend it is connecting to. This will make the HTTPS connection between the apiserver and the backend insecure. This means the apiserver cannot verify the log data it is receiving came from the real kubelet. If the kubelet is configured to verify the apiserver's TLS credentials, it does not mean the connection to the real kubelet is vulnerable to a man in the middle attack (e.g. an attacker could not intercept the actual log data coming from the real kubelet). +optional. | [optional] **grep** | **String**| | [optional] + **selector** | **String**| | [optional] ### Return type @@ -1139,7 +1141,7 @@ No authorization required # **workflowServiceWorkflowLogs** -> StreamResultOfIoArgoprojWorkflowV1alpha1LogEntry workflowServiceWorkflowLogs(namespace, name, podName, logOptionsContainer, logOptionsFollow, logOptionsPrevious, logOptionsSinceSeconds, logOptionsSinceTimeSeconds, logOptionsSinceTimeNanos, logOptionsTimestamps, logOptionsTailLines, logOptionsLimitBytes, logOptionsInsecureSkipTLSVerifyBackend, grep) +> StreamResultOfIoArgoprojWorkflowV1alpha1LogEntry workflowServiceWorkflowLogs(namespace, name, podName, logOptionsContainer, logOptionsFollow, logOptionsPrevious, logOptionsSinceSeconds, logOptionsSinceTimeSeconds, logOptionsSinceTimeNanos, logOptionsTimestamps, logOptionsTailLines, logOptionsLimitBytes, logOptionsInsecureSkipTLSVerifyBackend, grep, selector) @@ -1172,8 +1174,9 @@ public class Example { String logOptionsLimitBytes = "logOptionsLimitBytes_example"; // String | If set, the number of bytes to read from the server before terminating the log output. This may not display a complete final line of logging, and may return slightly more or slightly less than the specified limit. +optional. Boolean logOptionsInsecureSkipTLSVerifyBackend = true; // Boolean | insecureSkipTLSVerifyBackend indicates that the apiserver should not confirm the validity of the serving certificate of the backend it is connecting to. This will make the HTTPS connection between the apiserver and the backend insecure. This means the apiserver cannot verify the log data it is receiving came from the real kubelet. If the kubelet is configured to verify the apiserver's TLS credentials, it does not mean the connection to the real kubelet is vulnerable to a man in the middle attack (e.g. an attacker could not intercept the actual log data coming from the real kubelet). +optional. String grep = "grep_example"; // String | + String selector = "selector_example"; // String | try { - StreamResultOfIoArgoprojWorkflowV1alpha1LogEntry result = apiInstance.workflowServiceWorkflowLogs(namespace, name, podName, logOptionsContainer, logOptionsFollow, logOptionsPrevious, logOptionsSinceSeconds, logOptionsSinceTimeSeconds, logOptionsSinceTimeNanos, logOptionsTimestamps, logOptionsTailLines, logOptionsLimitBytes, logOptionsInsecureSkipTLSVerifyBackend, grep); + StreamResultOfIoArgoprojWorkflowV1alpha1LogEntry result = apiInstance.workflowServiceWorkflowLogs(namespace, name, podName, logOptionsContainer, logOptionsFollow, logOptionsPrevious, logOptionsSinceSeconds, logOptionsSinceTimeSeconds, logOptionsSinceTimeNanos, logOptionsTimestamps, logOptionsTailLines, logOptionsLimitBytes, logOptionsInsecureSkipTLSVerifyBackend, grep, selector); System.out.println(result); } catch (ApiException e) { System.err.println("Exception when calling WorkflowServiceApi#workflowServiceWorkflowLogs"); @@ -1204,6 +1207,7 @@ Name | Type | Description | Notes **logOptionsLimitBytes** | **String**| If set, the number of bytes to read from the server before terminating the log output. This may not display a complete final line of logging, and may return slightly more or slightly less than the specified limit. +optional. | [optional] **logOptionsInsecureSkipTLSVerifyBackend** | **Boolean**| insecureSkipTLSVerifyBackend indicates that the apiserver should not confirm the validity of the serving certificate of the backend it is connecting to. This will make the HTTPS connection between the apiserver and the backend insecure. This means the apiserver cannot verify the log data it is receiving came from the real kubelet. If the kubelet is configured to verify the apiserver's TLS credentials, it does not mean the connection to the real kubelet is vulnerable to a man in the middle attack (e.g. an attacker could not intercept the actual log data coming from the real kubelet). +optional. | [optional] **grep** | **String**| | [optional] + **selector** | **String**| | [optional] ### Return type diff --git a/sdks/python/client/docs/WorkflowServiceApi.md b/sdks/python/client/docs/WorkflowServiceApi.md index 3d59d1a4ea0a..c3e27260501e 100644 --- a/sdks/python/client/docs/WorkflowServiceApi.md +++ b/sdks/python/client/docs/WorkflowServiceApi.md @@ -40209,6 +40209,7 @@ with openapi_client.ApiClient() as api_client: log_options_limit_bytes = "logOptions.limitBytes_example" # str | If set, the number of bytes to read from the server before terminating the log output. This may not display a complete final line of logging, and may return slightly more or slightly less than the specified limit. +optional. (optional) log_options_insecure_skip_tls_verify_backend = True # bool | insecureSkipTLSVerifyBackend indicates that the apiserver should not confirm the validity of the serving certificate of the backend it is connecting to. This will make the HTTPS connection between the apiserver and the backend insecure. This means the apiserver cannot verify the log data it is receiving came from the real kubelet. If the kubelet is configured to verify the apiserver's TLS credentials, it does not mean the connection to the real kubelet is vulnerable to a man in the middle attack (e.g. an attacker could not intercept the actual log data coming from the real kubelet). +optional. (optional) grep = "grep_example" # str | (optional) + selector = "selector_example" # str | (optional) # example passing only required values which don't have defaults set try: @@ -40222,7 +40223,7 @@ with openapi_client.ApiClient() as api_client: # and optional values try: # DEPRECATED: Cannot work via HTTP if podName is an empty string. Use WorkflowLogs. - api_response = api_instance.workflow_service_pod_logs(namespace, name, pod_name, log_options_container=log_options_container, log_options_follow=log_options_follow, log_options_previous=log_options_previous, log_options_since_seconds=log_options_since_seconds, log_options_since_time_seconds=log_options_since_time_seconds, log_options_since_time_nanos=log_options_since_time_nanos, log_options_timestamps=log_options_timestamps, log_options_tail_lines=log_options_tail_lines, log_options_limit_bytes=log_options_limit_bytes, log_options_insecure_skip_tls_verify_backend=log_options_insecure_skip_tls_verify_backend, grep=grep) + api_response = api_instance.workflow_service_pod_logs(namespace, name, pod_name, log_options_container=log_options_container, log_options_follow=log_options_follow, log_options_previous=log_options_previous, log_options_since_seconds=log_options_since_seconds, log_options_since_time_seconds=log_options_since_time_seconds, log_options_since_time_nanos=log_options_since_time_nanos, log_options_timestamps=log_options_timestamps, log_options_tail_lines=log_options_tail_lines, log_options_limit_bytes=log_options_limit_bytes, log_options_insecure_skip_tls_verify_backend=log_options_insecure_skip_tls_verify_backend, grep=grep, selector=selector) pprint(api_response) except openapi_client.ApiException as e: print("Exception when calling WorkflowServiceApi->workflow_service_pod_logs: %s\n" % e) @@ -40247,6 +40248,7 @@ Name | Type | Description | Notes **log_options_limit_bytes** | **str**| If set, the number of bytes to read from the server before terminating the log output. This may not display a complete final line of logging, and may return slightly more or slightly less than the specified limit. +optional. | [optional] **log_options_insecure_skip_tls_verify_backend** | **bool**| insecureSkipTLSVerifyBackend indicates that the apiserver should not confirm the validity of the serving certificate of the backend it is connecting to. This will make the HTTPS connection between the apiserver and the backend insecure. This means the apiserver cannot verify the log data it is receiving came from the real kubelet. If the kubelet is configured to verify the apiserver's TLS credentials, it does not mean the connection to the real kubelet is vulnerable to a man in the middle attack (e.g. an attacker could not intercept the actual log data coming from the real kubelet). +optional. | [optional] **grep** | **str**| | [optional] + **selector** | **str**| | [optional] ### Return type @@ -41098,6 +41100,7 @@ with openapi_client.ApiClient() as api_client: log_options_limit_bytes = "logOptions.limitBytes_example" # str | If set, the number of bytes to read from the server before terminating the log output. This may not display a complete final line of logging, and may return slightly more or slightly less than the specified limit. +optional. (optional) log_options_insecure_skip_tls_verify_backend = True # bool | insecureSkipTLSVerifyBackend indicates that the apiserver should not confirm the validity of the serving certificate of the backend it is connecting to. This will make the HTTPS connection between the apiserver and the backend insecure. This means the apiserver cannot verify the log data it is receiving came from the real kubelet. If the kubelet is configured to verify the apiserver's TLS credentials, it does not mean the connection to the real kubelet is vulnerable to a man in the middle attack (e.g. an attacker could not intercept the actual log data coming from the real kubelet). +optional. (optional) grep = "grep_example" # str | (optional) + selector = "selector_example" # str | (optional) # example passing only required values which don't have defaults set try: @@ -41109,7 +41112,7 @@ with openapi_client.ApiClient() as api_client: # example passing only required values which don't have defaults set # and optional values try: - api_response = api_instance.workflow_service_workflow_logs(namespace, name, pod_name=pod_name, log_options_container=log_options_container, log_options_follow=log_options_follow, log_options_previous=log_options_previous, log_options_since_seconds=log_options_since_seconds, log_options_since_time_seconds=log_options_since_time_seconds, log_options_since_time_nanos=log_options_since_time_nanos, log_options_timestamps=log_options_timestamps, log_options_tail_lines=log_options_tail_lines, log_options_limit_bytes=log_options_limit_bytes, log_options_insecure_skip_tls_verify_backend=log_options_insecure_skip_tls_verify_backend, grep=grep) + api_response = api_instance.workflow_service_workflow_logs(namespace, name, pod_name=pod_name, log_options_container=log_options_container, log_options_follow=log_options_follow, log_options_previous=log_options_previous, log_options_since_seconds=log_options_since_seconds, log_options_since_time_seconds=log_options_since_time_seconds, log_options_since_time_nanos=log_options_since_time_nanos, log_options_timestamps=log_options_timestamps, log_options_tail_lines=log_options_tail_lines, log_options_limit_bytes=log_options_limit_bytes, log_options_insecure_skip_tls_verify_backend=log_options_insecure_skip_tls_verify_backend, grep=grep, selector=selector) pprint(api_response) except openapi_client.ApiException as e: print("Exception when calling WorkflowServiceApi->workflow_service_workflow_logs: %s\n" % e) @@ -41134,6 +41137,7 @@ Name | Type | Description | Notes **log_options_limit_bytes** | **str**| If set, the number of bytes to read from the server before terminating the log output. This may not display a complete final line of logging, and may return slightly more or slightly less than the specified limit. +optional. | [optional] **log_options_insecure_skip_tls_verify_backend** | **bool**| insecureSkipTLSVerifyBackend indicates that the apiserver should not confirm the validity of the serving certificate of the backend it is connecting to. This will make the HTTPS connection between the apiserver and the backend insecure. This means the apiserver cannot verify the log data it is receiving came from the real kubelet. If the kubelet is configured to verify the apiserver's TLS credentials, it does not mean the connection to the real kubelet is vulnerable to a man in the middle attack (e.g. an attacker could not intercept the actual log data coming from the real kubelet). +optional. | [optional] **grep** | **str**| | [optional] + **selector** | **str**| | [optional] ### Return type diff --git a/sdks/python/client/openapi_client/api/workflow_service_api.py b/sdks/python/client/openapi_client/api/workflow_service_api.py index a5eab405ea30..011dd4131d90 100644 --- a/sdks/python/client/openapi_client/api/workflow_service_api.py +++ b/sdks/python/client/openapi_client/api/workflow_service_api.py @@ -814,6 +814,7 @@ def __workflow_service_pod_logs( log_options_limit_bytes (str): If set, the number of bytes to read from the server before terminating the log output. This may not display a complete final line of logging, and may return slightly more or slightly less than the specified limit. +optional.. [optional] log_options_insecure_skip_tls_verify_backend (bool): insecureSkipTLSVerifyBackend indicates that the apiserver should not confirm the validity of the serving certificate of the backend it is connecting to. This will make the HTTPS connection between the apiserver and the backend insecure. This means the apiserver cannot verify the log data it is receiving came from the real kubelet. If the kubelet is configured to verify the apiserver's TLS credentials, it does not mean the connection to the real kubelet is vulnerable to a man in the middle attack (e.g. an attacker could not intercept the actual log data coming from the real kubelet). +optional.. [optional] grep (str): [optional] + selector (str): [optional] _return_http_data_only (bool): response data without head status code and headers. Default is True. _preload_content (bool): if False, the urllib3.HTTPResponse object @@ -891,6 +892,7 @@ def __workflow_service_pod_logs( 'log_options_limit_bytes', 'log_options_insecure_skip_tls_verify_backend', 'grep', + 'selector', ], 'required': [ 'namespace', @@ -938,6 +940,8 @@ def __workflow_service_pod_logs( (bool,), 'grep': (str,), + 'selector': + (str,), }, 'attribute_map': { 'namespace': 'namespace', @@ -954,6 +958,7 @@ def __workflow_service_pod_logs( 'log_options_limit_bytes': 'logOptions.limitBytes', 'log_options_insecure_skip_tls_verify_backend': 'logOptions.insecureSkipTLSVerifyBackend', 'grep': 'grep', + 'selector': 'selector', }, 'location_map': { 'namespace': 'path', @@ -970,6 +975,7 @@ def __workflow_service_pod_logs( 'log_options_limit_bytes': 'query', 'log_options_insecure_skip_tls_verify_backend': 'query', 'grep': 'query', + 'selector': 'query', }, 'collection_format_map': { } @@ -2447,6 +2453,7 @@ def __workflow_service_workflow_logs( log_options_limit_bytes (str): If set, the number of bytes to read from the server before terminating the log output. This may not display a complete final line of logging, and may return slightly more or slightly less than the specified limit. +optional.. [optional] log_options_insecure_skip_tls_verify_backend (bool): insecureSkipTLSVerifyBackend indicates that the apiserver should not confirm the validity of the serving certificate of the backend it is connecting to. This will make the HTTPS connection between the apiserver and the backend insecure. This means the apiserver cannot verify the log data it is receiving came from the real kubelet. If the kubelet is configured to verify the apiserver's TLS credentials, it does not mean the connection to the real kubelet is vulnerable to a man in the middle attack (e.g. an attacker could not intercept the actual log data coming from the real kubelet). +optional.. [optional] grep (str): [optional] + selector (str): [optional] _return_http_data_only (bool): response data without head status code and headers. Default is True. _preload_content (bool): if False, the urllib3.HTTPResponse object @@ -2522,6 +2529,7 @@ def __workflow_service_workflow_logs( 'log_options_limit_bytes', 'log_options_insecure_skip_tls_verify_backend', 'grep', + 'selector', ], 'required': [ 'namespace', @@ -2568,6 +2576,8 @@ def __workflow_service_workflow_logs( (bool,), 'grep': (str,), + 'selector': + (str,), }, 'attribute_map': { 'namespace': 'namespace', @@ -2584,6 +2594,7 @@ def __workflow_service_workflow_logs( 'log_options_limit_bytes': 'logOptions.limitBytes', 'log_options_insecure_skip_tls_verify_backend': 'logOptions.insecureSkipTLSVerifyBackend', 'grep': 'grep', + 'selector': 'selector', }, 'location_map': { 'namespace': 'path', @@ -2600,6 +2611,7 @@ def __workflow_service_workflow_logs( 'log_options_limit_bytes': 'query', 'log_options_insecure_skip_tls_verify_backend': 'query', 'grep': 'query', + 'selector': 'query', }, 'collection_format_map': { } diff --git a/util/logs/workflow-logger.go b/util/logs/workflow-logger.go index 40e1c18ea7af..2cc93acfe2f6 100644 --- a/util/logs/workflow-logger.go +++ b/util/logs/workflow-logger.go @@ -34,6 +34,7 @@ type request interface { GetPodName() string GetLogOptions() *corev1.PodLogOptions GetGrep() string + GetSelector() string } type sender interface { @@ -56,9 +57,19 @@ func WorkflowLogs(ctx context.Context, wfClient versioned.Interface, kubeClient logCtx := log.WithFields(log.Fields{"workflow": req.GetName(), "namespace": req.GetNamespace()}) - // we create a watch on the pods labelled with the workflow name, - // but we also filter by pod name if that was requested - podListOptions := metav1.ListOptions{LabelSelector: common.LabelKeyWorkflow + "=" + req.GetName()} + var podListOptions metav1.ListOptions + + // we add selector if cli specify the pod selector when using logs + if req.GetSelector() != "" { + podListOptions = metav1.ListOptions{LabelSelector: common.LabelKeyWorkflow + "=" + req.GetName() + "," + req.GetSelector()} + + } else { + // we create a watch on the pods labelled with the workflow name, + // but we also filter by pod name if that was requested + podListOptions = metav1.ListOptions{LabelSelector: common.LabelKeyWorkflow + "=" + req.GetName()} + + } + if req.GetPodName() != "" { podListOptions.FieldSelector = "metadata.name=" + req.GetPodName() }