From 6d14998a998e392590a8871da87514f5bffa6a46 Mon Sep 17 00:00:00 2001 From: Derek Wang Date: Tue, 18 Jul 2023 08:56:41 -0700 Subject: [PATCH] feat: controller changes for Side Inputs support (#866) Signed-off-by: Derek Wang --- api/json-schema/schema.json | 212 +- api/openapi-spec/swagger.json | 204 +- cmd/commands/daemon_server.go | 4 +- cmd/commands/isbsvc_create.go | 16 +- cmd/commands/isbsvc_delete.go | 16 +- cmd/commands/isbsvc_validate.go | 18 +- cmd/commands/root.go | 3 + cmd/commands/side_inputs_init.go | 60 + cmd/commands/side_inputs_manager.go | 70 + cmd/commands/side_inputs_watcher.go | 61 + .../full/numaflow.numaproj.io_pipelines.yaml | 2442 ++++++++++++++-- .../full/numaflow.numaproj.io_vertices.yaml | 170 ++ config/install.yaml | 2594 +++++++++++++++-- config/namespace-install.yaml | 2594 +++++++++++++++-- docs/APIs.md | 322 +- docs/specifications/side-inputs.md | 2 +- pkg/apis/numaflow/v1alpha1/const.go | 28 +- .../numaflow/v1alpha1/container_template.go | 2 +- pkg/apis/numaflow/v1alpha1/generated.pb.go | 2517 ++++++++++++---- pkg/apis/numaflow/v1alpha1/generated.proto | 80 +- pkg/apis/numaflow/v1alpha1/get_spec_req.go | 16 +- .../numaflow/v1alpha1/openapi_generated.go | 381 ++- pkg/apis/numaflow/v1alpha1/pipeline_types.go | 55 +- .../numaflow/v1alpha1/pipeline_types_test.go | 27 + pkg/apis/numaflow/v1alpha1/side_inputs.go | 184 ++ .../numaflow/v1alpha1/side_inputs_test.go | 102 + pkg/apis/numaflow/v1alpha1/vertex_types.go | 76 +- .../numaflow/v1alpha1/vertex_types_test.go | 20 + .../v1alpha1/zz_generated.deepcopy.go | 136 + .../service/pipeline_metrics_query_test.go | 6 +- .../server/service/rater/pod_tracker_test.go | 16 + pkg/isbsvc/interface.go | 6 +- pkg/isbsvc/jetstream_service.go | 46 +- pkg/isbsvc/redis_service.go | 6 +- pkg/isbsvc/redis_service_test.go | 6 +- pkg/reconciler/pipeline/controller.go | 85 + pkg/reconciler/pipeline/controller_test.go | 100 + pkg/reconciler/pipeline/validate.go | 51 +- pkg/reconciler/pipeline/validate_test.go | 72 + pkg/reconciler/vertex/controller.go | 9 +- pkg/reconciler/vertex/controller_test.go | 51 + pkg/sdkclient/error/error.go | 16 + pkg/sdkclient/error/error_test.go | 16 + pkg/sdkclient/sink/client/client.go | 16 + pkg/sdkclient/sink/client/interface.go | 16 + pkg/sdkclient/sink/client/options.go | 16 + pkg/sdkclient/sink/clienttest/client_test.go | 16 + pkg/sdkclient/sink/clienttest/clienttest.go | 16 + pkg/sdkclient/udf/client/client.go | 16 + pkg/sdkclient/udf/client/client_resolver.go | 16 + pkg/sdkclient/udf/client/interface.go | 16 + pkg/sdkclient/udf/client/options.go | 16 + pkg/sdkclient/udf/clienttest/client_test.go | 16 + pkg/sdkclient/udf/clienttest/clienttest.go | 16 + pkg/sideinputs/doc.go | 23 + pkg/sideinputs/initializer/doc.go | 18 + pkg/sideinputs/initializer/initializer.go | 76 + pkg/sideinputs/manager/doc.go | 18 + pkg/sideinputs/manager/manager.go | 75 + pkg/sideinputs/watcher/doc.go | 18 + pkg/sideinputs/watcher/watcher.go | 79 + pkg/watermark/wmb/checker_test.go | 16 + pkg/watermark/wmb/idle_manager_test.go | 16 + server/doc.go | 18 + webhook/cmd/start.go | 27 +- webhook/doc.go | 18 + webhook/validator/isbsvc.go | 21 +- webhook/validator/isbsvc_test.go | 16 + webhook/validator/pipeline.go | 21 +- webhook/validator/pipeline_test.go | 16 + webhook/validator/validator.go | 28 +- webhook/validator/validator_test.go | 16 + webhook/webhook.go | 27 +- webhook/webhook_test.go | 21 +- 74 files changed, 12139 insertions(+), 1503 deletions(-) create mode 100644 cmd/commands/side_inputs_init.go create mode 100644 cmd/commands/side_inputs_manager.go create mode 100644 cmd/commands/side_inputs_watcher.go create mode 100644 pkg/apis/numaflow/v1alpha1/side_inputs.go create mode 100644 pkg/apis/numaflow/v1alpha1/side_inputs_test.go create mode 100644 pkg/sideinputs/doc.go create mode 100644 pkg/sideinputs/initializer/doc.go create mode 100644 pkg/sideinputs/initializer/initializer.go create mode 100644 pkg/sideinputs/manager/doc.go create mode 100644 pkg/sideinputs/manager/manager.go create mode 100644 pkg/sideinputs/watcher/doc.go create mode 100644 pkg/sideinputs/watcher/watcher.go create mode 100644 server/doc.go create mode 100644 webhook/doc.go diff --git a/api/json-schema/schema.json b/api/json-schema/schema.json index 2486113b9..071a9695f 100644 --- a/api/json-schema/schema.json +++ b/api/json-schema/schema.json @@ -17334,7 +17334,8 @@ "type": "boolean" }, "containerTemplate": { - "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate" + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate", + "description": "Container template for the main numa container." }, "dnsConfig": { "$ref": "#/definitions/io.k8s.api.core.v1.PodDNSConfig", @@ -17354,10 +17355,11 @@ "x-kubernetes-patch-strategy": "merge" }, "initContainerTemplate": { - "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate" + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate", + "description": "Container template for all the vertex pod init containers spawned by numaflow, excluding the ones specified by the user." }, "initContainers": { - "description": "List of init containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", + "description": "List of customized init containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", "items": { "$ref": "#/definitions/io.k8s.api.core.v1.Container" }, @@ -17411,8 +17413,19 @@ "description": "ServiceAccountName applied to the pod", "type": "string" }, + "sideInputs": { + "description": "Names of the side inputs used in this vertex.", + "items": { + "type": "string" + }, + "type": "array" + }, + "sideInputsContainerTemplate": { + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate", + "description": "Container template for the side inputs watcher container." + }, "sidecars": { - "description": "List of sidecar containers belonging to the pod.", + "description": "List of customized sidecar containers belonging to the pod.", "items": { "$ref": "#/definitions/io.k8s.api.core.v1.Container" }, @@ -18050,7 +18063,7 @@ ], "type": "object" }, - "io.numaproj.numaflow.v1alpha1.GetVertexPodSpecReq": { + "io.numaproj.numaflow.v1alpha1.GetSideInputDeploymentReq": { "properties": { "Env": { "items": { @@ -18076,6 +18089,36 @@ ], "type": "object" }, + "io.numaproj.numaflow.v1alpha1.GetVertexPodSpecReq": { + "properties": { + "Env": { + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.EnvVar" + }, + "type": "array" + }, + "ISBSvcType": { + "type": "string" + }, + "Image": { + "type": "string" + }, + "PullPolicy": { + "type": "string" + }, + "SideInputsStoreName": { + "type": "string" + } + }, + "required": [ + "ISBSvcType", + "Image", + "PullPolicy", + "Env", + "SideInputsStoreName" + ], + "type": "object" + }, "io.numaproj.numaflow.v1alpha1.GroupBy": { "description": "GroupBy indicates it is a reducer UDF", "properties": { @@ -18735,7 +18778,7 @@ "io.numaproj.numaflow.v1alpha1.PipelineLimits": { "properties": { "bufferMaxLength": { - "description": "BufferMaxLength is used to define the max length of a buffer Only applies to UDF and Source vertices as only they do buffer write. It can be overridden by the settings in vertex limits.", + "description": "BufferMaxLength is used to define the max length of a buffer. Only applies to UDF and Source vertices as only they do buffer write. It can be overridden by the settings in vertex limits.", "format": "int64", "type": "integer" }, @@ -18745,7 +18788,7 @@ "type": "integer" }, "readBatchSize": { - "description": "Read batch size for all the vertices in the pipeline, can be overridden by the vertex's limit settings", + "description": "Read batch size for all the vertices in the pipeline, can be overridden by the vertex's limit settings.", "format": "int64", "type": "integer" }, @@ -18801,6 +18844,13 @@ "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.PipelineLimits", "description": "Limits define the limitations such as buffer read batch size for all the vertices of a pipeline, they could be overridden by each vertex's settings" }, + "sideInputs": { + "description": "SideInputs defines the Side Inputs of a pipeline.", + "items": { + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.SideInput" + }, + "type": "array" + }, "templates": { "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.Templates", "description": "Templates is used to customize additional kubernetes resources required for the Pipeline" @@ -19059,6 +19109,125 @@ }, "type": "object" }, + "io.numaproj.numaflow.v1alpha1.SideInput": { + "description": "SideInput defines information of a Side Input", + "properties": { + "container": { + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.Container" + }, + "name": { + "type": "string" + }, + "trigger": { + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.SideInputTrigger" + }, + "volumes": { + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Volume" + }, + "type": "array", + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge" + } + }, + "required": [ + "name", + "container", + "trigger" + ], + "type": "object" + }, + "io.numaproj.numaflow.v1alpha1.SideInputTrigger": { + "properties": { + "interval": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Duration" + }, + "schedule": { + "type": "string" + }, + "timezone": { + "type": "string" + } + }, + "type": "object" + }, + "io.numaproj.numaflow.v1alpha1.SideInputsManagerTemplate": { + "properties": { + "affinity": { + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity", + "description": "The pod's scheduling constraints More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/" + }, + "automountServiceAccountToken": { + "description": "AutomountServiceAccountToken indicates whether a service account token should be automatically mounted.", + "type": "boolean" + }, + "containerTemplate": { + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate", + "description": "Template for the side inputs manager numa container" + }, + "dnsConfig": { + "$ref": "#/definitions/io.k8s.api.core.v1.PodDNSConfig", + "description": "Specifies the DNS parameters of a pod. Parameters specified here will be merged to the generated DNS configuration based on DNSPolicy." + }, + "dnsPolicy": { + "description": "Set DNS policy for the pod. Defaults to \"ClusterFirst\". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.", + "type": "string" + }, + "imagePullSecrets": { + "description": "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.LocalObjectReference" + }, + "type": "array", + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge" + }, + "initContainerTemplate": { + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate", + "description": "Template for the side inputs manager init container" + }, + "metadata": { + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.Metadata", + "description": "Metadata sets the pods's metadata, i.e. annotations and labels" + }, + "nodeSelector": { + "additionalProperties": { + "type": "string" + }, + "description": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/", + "type": "object" + }, + "priority": { + "description": "The priority value. Various system components use this field to find the priority of the Redis pod. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. More info: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/", + "format": "int32", + "type": "integer" + }, + "priorityClassName": { + "description": "If specified, indicates the Redis pod's priority. \"system-node-critical\" and \"system-cluster-critical\" are two special keywords which indicate the highest priorities with the former being the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default. More info: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/", + "type": "string" + }, + "runtimeClassName": { + "description": "RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. If unset or empty, the \"legacy\" RuntimeClass will be used, which is an implicit class with an empty definition that uses the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class", + "type": "string" + }, + "securityContext": { + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext", + "description": "SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field." + }, + "serviceAccountName": { + "description": "ServiceAccountName applied to the pod", + "type": "string" + }, + "tolerations": { + "description": "If specified, the pod's tolerations.", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + }, + "type": "array" + } + }, + "type": "object" + }, "io.numaproj.numaflow.v1alpha1.Sink": { "properties": { "blackhole": { @@ -19169,11 +19338,15 @@ "properties": { "daemon": { "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.DaemonTemplate", - "description": "DaemonTemplate is used to customize the Daemon Deployment" + "description": "DaemonTemplate is used to customize the Daemon Deployment." }, "job": { "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.JobTemplate", - "description": "JobTemplate is used to customize Jobs" + "description": "JobTemplate is used to customize Jobs." + }, + "sideInputsManager": { + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.SideInputsManagerTemplate", + "description": "SideInputsManagerTemplate is used to customize the Side Inputs Manager." } }, "type": "object" @@ -19347,7 +19520,8 @@ "type": "boolean" }, "containerTemplate": { - "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate" + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate", + "description": "Container template for the main numa container." }, "dnsConfig": { "$ref": "#/definitions/io.k8s.api.core.v1.PodDNSConfig", @@ -19373,10 +19547,11 @@ "x-kubernetes-patch-strategy": "merge" }, "initContainerTemplate": { - "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate" + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate", + "description": "Container template for all the vertex pod init containers spawned by numaflow, excluding the ones specified by the user." }, "initContainers": { - "description": "List of init containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", + "description": "List of customized init containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", "items": { "$ref": "#/definitions/io.k8s.api.core.v1.Container" }, @@ -19440,8 +19615,19 @@ "description": "ServiceAccountName applied to the pod", "type": "string" }, + "sideInputs": { + "description": "Names of the side inputs used in this vertex.", + "items": { + "type": "string" + }, + "type": "array" + }, + "sideInputsContainerTemplate": { + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate", + "description": "Container template for the side inputs watcher container." + }, "sidecars": { - "description": "List of sidecar containers belonging to the pod.", + "description": "List of customized sidecar containers belonging to the pod.", "items": { "$ref": "#/definitions/io.k8s.api.core.v1.Container" }, diff --git a/api/openapi-spec/swagger.json b/api/openapi-spec/swagger.json index d921cbe2f..ee84385bc 100644 --- a/api/openapi-spec/swagger.json +++ b/api/openapi-spec/swagger.json @@ -17342,6 +17342,7 @@ "type": "boolean" }, "containerTemplate": { + "description": "Container template for the main numa container.", "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate" }, "dnsConfig": { @@ -17362,10 +17363,11 @@ "x-kubernetes-patch-strategy": "merge" }, "initContainerTemplate": { + "description": "Container template for all the vertex pod init containers spawned by numaflow, excluding the ones specified by the user.", "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate" }, "initContainers": { - "description": "List of init containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", + "description": "List of customized init containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", "type": "array", "items": { "$ref": "#/definitions/io.k8s.api.core.v1.Container" @@ -17419,8 +17421,19 @@ "description": "ServiceAccountName applied to the pod", "type": "string" }, + "sideInputs": { + "description": "Names of the side inputs used in this vertex.", + "type": "array", + "items": { + "type": "string" + } + }, + "sideInputsContainerTemplate": { + "description": "Container template for the side inputs watcher container.", + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate" + }, "sidecars": { - "description": "List of sidecar containers belonging to the pod.", + "description": "List of customized sidecar containers belonging to the pod.", "type": "array", "items": { "$ref": "#/definitions/io.k8s.api.core.v1.Container" @@ -18054,7 +18067,7 @@ } } }, - "io.numaproj.numaflow.v1alpha1.GetVertexPodSpecReq": { + "io.numaproj.numaflow.v1alpha1.GetSideInputDeploymentReq": { "type": "object", "required": [ "ISBSvcType", @@ -18080,6 +18093,36 @@ } } }, + "io.numaproj.numaflow.v1alpha1.GetVertexPodSpecReq": { + "type": "object", + "required": [ + "ISBSvcType", + "Image", + "PullPolicy", + "Env", + "SideInputsStoreName" + ], + "properties": { + "Env": { + "type": "array", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.EnvVar" + } + }, + "ISBSvcType": { + "type": "string" + }, + "Image": { + "type": "string" + }, + "PullPolicy": { + "type": "string" + }, + "SideInputsStoreName": { + "type": "string" + } + } + }, "io.numaproj.numaflow.v1alpha1.GroupBy": { "description": "GroupBy indicates it is a reducer UDF", "type": "object", @@ -18722,7 +18765,7 @@ "type": "object", "properties": { "bufferMaxLength": { - "description": "BufferMaxLength is used to define the max length of a buffer Only applies to UDF and Source vertices as only they do buffer write. It can be overridden by the settings in vertex limits.", + "description": "BufferMaxLength is used to define the max length of a buffer. Only applies to UDF and Source vertices as only they do buffer write. It can be overridden by the settings in vertex limits.", "type": "integer", "format": "int64" }, @@ -18732,7 +18775,7 @@ "format": "int64" }, "readBatchSize": { - "description": "Read batch size for all the vertices in the pipeline, can be overridden by the vertex's limit settings", + "description": "Read batch size for all the vertices in the pipeline, can be overridden by the vertex's limit settings.", "type": "integer", "format": "int64" }, @@ -18788,6 +18831,13 @@ "description": "Limits define the limitations such as buffer read batch size for all the vertices of a pipeline, they could be overridden by each vertex's settings", "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.PipelineLimits" }, + "sideInputs": { + "description": "SideInputs defines the Side Inputs of a pipeline.", + "type": "array", + "items": { + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.SideInput" + } + }, "templates": { "description": "Templates is used to customize additional kubernetes resources required for the Pipeline", "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.Templates" @@ -19045,6 +19095,125 @@ } } }, + "io.numaproj.numaflow.v1alpha1.SideInput": { + "description": "SideInput defines information of a Side Input", + "type": "object", + "required": [ + "name", + "container", + "trigger" + ], + "properties": { + "container": { + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.Container" + }, + "name": { + "type": "string" + }, + "trigger": { + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.SideInputTrigger" + }, + "volumes": { + "type": "array", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Volume" + }, + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge" + } + } + }, + "io.numaproj.numaflow.v1alpha1.SideInputTrigger": { + "type": "object", + "properties": { + "interval": { + "$ref": "#/definitions/io.k8s.apimachinery.pkg.apis.meta.v1.Duration" + }, + "schedule": { + "type": "string" + }, + "timezone": { + "type": "string" + } + } + }, + "io.numaproj.numaflow.v1alpha1.SideInputsManagerTemplate": { + "type": "object", + "properties": { + "affinity": { + "description": "The pod's scheduling constraints More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/", + "$ref": "#/definitions/io.k8s.api.core.v1.Affinity" + }, + "automountServiceAccountToken": { + "description": "AutomountServiceAccountToken indicates whether a service account token should be automatically mounted.", + "type": "boolean" + }, + "containerTemplate": { + "description": "Template for the side inputs manager numa container", + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate" + }, + "dnsConfig": { + "description": "Specifies the DNS parameters of a pod. Parameters specified here will be merged to the generated DNS configuration based on DNSPolicy.", + "$ref": "#/definitions/io.k8s.api.core.v1.PodDNSConfig" + }, + "dnsPolicy": { + "description": "Set DNS policy for the pod. Defaults to \"ClusterFirst\". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.", + "type": "string" + }, + "imagePullSecrets": { + "description": "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod", + "type": "array", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.LocalObjectReference" + }, + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge" + }, + "initContainerTemplate": { + "description": "Template for the side inputs manager init container", + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate" + }, + "metadata": { + "description": "Metadata sets the pods's metadata, i.e. annotations and labels", + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.Metadata" + }, + "nodeSelector": { + "description": "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/", + "type": "object", + "additionalProperties": { + "type": "string" + } + }, + "priority": { + "description": "The priority value. Various system components use this field to find the priority of the Redis pod. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. More info: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/", + "type": "integer", + "format": "int32" + }, + "priorityClassName": { + "description": "If specified, indicates the Redis pod's priority. \"system-node-critical\" and \"system-cluster-critical\" are two special keywords which indicate the highest priorities with the former being the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default. More info: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/", + "type": "string" + }, + "runtimeClassName": { + "description": "RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. If unset or empty, the \"legacy\" RuntimeClass will be used, which is an implicit class with an empty definition that uses the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class", + "type": "string" + }, + "securityContext": { + "description": "SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field.", + "$ref": "#/definitions/io.k8s.api.core.v1.PodSecurityContext" + }, + "serviceAccountName": { + "description": "ServiceAccountName applied to the pod", + "type": "string" + }, + "tolerations": { + "description": "If specified, the pod's tolerations.", + "type": "array", + "items": { + "$ref": "#/definitions/io.k8s.api.core.v1.Toleration" + } + } + } + }, "io.numaproj.numaflow.v1alpha1.Sink": { "type": "object", "properties": { @@ -19155,12 +19324,16 @@ "type": "object", "properties": { "daemon": { - "description": "DaemonTemplate is used to customize the Daemon Deployment", + "description": "DaemonTemplate is used to customize the Daemon Deployment.", "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.DaemonTemplate" }, "job": { - "description": "JobTemplate is used to customize Jobs", + "description": "JobTemplate is used to customize Jobs.", "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.JobTemplate" + }, + "sideInputsManager": { + "description": "SideInputsManagerTemplate is used to customize the Side Inputs Manager.", + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.SideInputsManagerTemplate" } } }, @@ -19329,6 +19502,7 @@ "type": "boolean" }, "containerTemplate": { + "description": "Container template for the main numa container.", "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate" }, "dnsConfig": { @@ -19355,10 +19529,11 @@ "x-kubernetes-patch-strategy": "merge" }, "initContainerTemplate": { + "description": "Container template for all the vertex pod init containers spawned by numaflow, excluding the ones specified by the user.", "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate" }, "initContainers": { - "description": "List of init containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", + "description": "List of customized init containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", "type": "array", "items": { "$ref": "#/definitions/io.k8s.api.core.v1.Container" @@ -19422,8 +19597,19 @@ "description": "ServiceAccountName applied to the pod", "type": "string" }, + "sideInputs": { + "description": "Names of the side inputs used in this vertex.", + "type": "array", + "items": { + "type": "string" + } + }, + "sideInputsContainerTemplate": { + "description": "Container template for the side inputs watcher container.", + "$ref": "#/definitions/io.numaproj.numaflow.v1alpha1.ContainerTemplate" + }, "sidecars": { - "description": "List of sidecar containers belonging to the pod.", + "description": "List of customized sidecar containers belonging to the pod.", "type": "array", "items": { "$ref": "#/definitions/io.k8s.api.core.v1.Container" diff --git a/cmd/commands/daemon_server.go b/cmd/commands/daemon_server.go index d66551620..e0edb08f5 100644 --- a/cmd/commands/daemon_server.go +++ b/cmd/commands/daemon_server.go @@ -17,13 +17,13 @@ limitations under the License. package commands import ( - "context" "encoding/base64" "encoding/json" "fmt" "os" "github.com/spf13/cobra" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" "github.com/numaproj/numaflow/pkg/daemon/server" @@ -46,7 +46,7 @@ func NewDaemonServerCommand() *cobra.Command { return fmt.Errorf("failed to decode the pipeline spec: %v", err) } - ctx := logging.WithLogger(context.Background(), logger) + ctx := logging.WithLogger(signals.SetupSignalHandler(), logger) server := server.NewDaemonServer(pl, v1alpha1.ISBSvcType(isbSvcType)) return server.Run(ctx) }, diff --git a/cmd/commands/isbsvc_create.go b/cmd/commands/isbsvc_create.go index f5a1f3ca9..b767099e0 100644 --- a/cmd/commands/isbsvc_create.go +++ b/cmd/commands/isbsvc_create.go @@ -35,14 +35,15 @@ import ( func NewISBSvcCreateCommand() *cobra.Command { var ( - isbSvcType string - buffers []string - buckets []string + isbSvcType string + buffers []string + buckets []string + sideInputsStore string ) command := &cobra.Command{ Use: "isbsvc-create", - Short: "Create buffers and buckets", + Short: "Create buffers, buckets and side inputs store", RunE: func(cmd *cobra.Command, args []string) error { logger := logging.NewLogger().Named("isbsvc-create") pipelineName, defined := os.LookupEnv(v1alpha1.EnvPipelineName) @@ -79,16 +80,17 @@ func NewISBSvcCreateCommand() *cobra.Command { return fmt.Errorf("unsupported isb service type %q", isbSvcType) } - if err = isbsClient.CreateBuffersAndBuckets(ctx, buffers, buckets, opts...); err != nil { - logger.Errorw("Failed to create buffers and buckets.", zap.Error(err)) + if err = isbsClient.CreateBuffersAndBuckets(ctx, buffers, buckets, sideInputsStore, opts...); err != nil { + logger.Errorw("Failed to create buffers, buckets and side inputs store.", zap.Error(err)) return err } - logger.Info("Created buffers and buckets successfully") + logger.Info("Created buffers, buckets and side inputs store successfully") return nil }, } command.Flags().StringVar(&isbSvcType, "isbsvc-type", "", "ISB Service type, e.g. jetstream") command.Flags().StringSliceVar(&buffers, "buffers", []string{}, "Buffers to create") // --buffers=a,b, --buffers=c command.Flags().StringSliceVar(&buckets, "buckets", []string{}, "Buckets to create") // --buckets=xxa,xxb --buckets=xxc + command.Flags().StringVar(&sideInputsStore, "side-inputs-store", "", "Name of the side inputs store") return command } diff --git a/cmd/commands/isbsvc_delete.go b/cmd/commands/isbsvc_delete.go index bd86f45ca..aaf431826 100644 --- a/cmd/commands/isbsvc_delete.go +++ b/cmd/commands/isbsvc_delete.go @@ -32,14 +32,15 @@ import ( func NewISBSvcDeleteCommand() *cobra.Command { var ( - isbSvcType string - buffers []string - buckets []string + isbSvcType string + buffers []string + buckets []string + sideInputsStore string ) command := &cobra.Command{ Use: "isbsvc-delete", - Short: "Delete ISB Service buffers and buckets", + Short: "Delete ISB Service buffers, buckets and side inputs store", RunE: func(cmd *cobra.Command, args []string) error { logger := logging.NewLogger().Named("isbsvc-delete") pipelineName, defined := os.LookupEnv(v1alpha1.EnvPipelineName) @@ -62,16 +63,17 @@ func NewISBSvcDeleteCommand() *cobra.Command { cmd.HelpFunc()(cmd, args) return fmt.Errorf("unsupported isb service type %q", isbSvcType) } - if err = isbsClient.DeleteBuffersAndBuckets(ctx, buffers, buckets); err != nil { - logger.Errorw("Failed on buffers and buckets deletion.", zap.Error(err)) + if err = isbsClient.DeleteBuffersAndBuckets(ctx, buffers, buckets, sideInputsStore); err != nil { + logger.Errorw("Failed on buffers, buckets and side inputs store deletion.", zap.Error(err)) return err } - logger.Info("Deleted buffers and buckets successfully") + logger.Info("Deleted buffers, buckets and side inputs store successfully") return nil }, } command.Flags().StringVar(&isbSvcType, "isbsvc-type", "", "ISB Service type, e.g. jetstream") command.Flags().StringSliceVar(&buffers, "buffers", []string{}, "Buffers to delete") // --buffers=a,b, --buffers=c command.Flags().StringSliceVar(&buckets, "buckets", []string{}, "Buckets to delete") // --buckets=xxa,xxb --buckets=xxc return command + command.Flags().StringVar(&sideInputsStore, "side-inputs-store", "", "Name of the side inputs store") return command } diff --git a/cmd/commands/isbsvc_validate.go b/cmd/commands/isbsvc_validate.go index a1363240d..84c1b699c 100644 --- a/cmd/commands/isbsvc_validate.go +++ b/cmd/commands/isbsvc_validate.go @@ -35,14 +35,15 @@ import ( func NewISBSvcValidateCommand() *cobra.Command { var ( - isbSvcType string - buffers []string - buckets []string + isbSvcType string + buffers []string + buckets []string + sideInputsStore string ) command := &cobra.Command{ Use: "isbsvc-validate", - Short: "Validate ISB Service buffers and buckets", + Short: "Validate ISB Service buffers, buckets and side inputs store", RunE: func(cmd *cobra.Command, args []string) error { logger := logging.NewLogger().Named("isbsvc-validate") pipelineName, existing := os.LookupEnv(v1alpha1.EnvPipelineName) @@ -66,22 +67,23 @@ func NewISBSvcValidateCommand() *cobra.Command { return fmt.Errorf("unsupported isb service type") } _ = wait.ExponentialBackoffWithContext(ctx, sharedutil.DefaultRetryBackoff, func() (bool, error) { - if err = isbsClient.ValidateBuffersAndBuckets(ctx, buffers, buckets); err != nil { - logger.Infow("Buffers and buckets might have not been created yet, will retry if the limit is not reached", zap.Error(err)) + if err = isbsClient.ValidateBuffersAndBuckets(ctx, buffers, buckets, sideInputsStore); err != nil { + logger.Infow("Buffers, buckets and side inputs store might have not been created yet, will retry if the limit is not reached", zap.Error(err)) return false, nil } return true, nil }) if err != nil { - logger.Errorw("Failed on buffer and bucket validation after retrying.", zap.Error(err)) + logger.Errorw("Failed buffer, bucket and side inputs store validation after retrying.", zap.Error(err)) return err } - logger.Info("Validate buffers and buckets successfully") + logger.Info("Validate buffers, buckets and side inputs store successfully") return nil }, } command.Flags().StringVar(&isbSvcType, "isbsvc-type", "", "ISB Service type, e.g. jetstream") command.Flags().StringSliceVar(&buffers, "buffers", []string{}, "Buffers to validate") // --buffers=a,b, --buffers=c command.Flags().StringSliceVar(&buckets, "buckets", []string{}, "Buckets to validate") // --buckets=xxa,xxb --buckets=xxc + command.Flags().StringVar(&sideInputsStore, "side-inputs-store", "", "Name of the side inputs store") return command } diff --git a/cmd/commands/root.go b/cmd/commands/root.go index bf3c4914a..9702c5839 100644 --- a/cmd/commands/root.go +++ b/cmd/commands/root.go @@ -46,4 +46,7 @@ func init() { rootCmd.AddCommand(NewServerCommand()) rootCmd.AddCommand(NewServerInitCommand()) rootCmd.AddCommand(NewWebhookCommand()) + rootCmd.AddCommand(NewSideInputsInitCommand()) + rootCmd.AddCommand(NewSideInputsManagerCommand()) + rootCmd.AddCommand(NewSideInputsWatcherCommand()) } diff --git a/cmd/commands/side_inputs_init.go b/cmd/commands/side_inputs_init.go new file mode 100644 index 000000000..4233c07c2 --- /dev/null +++ b/cmd/commands/side_inputs_init.go @@ -0,0 +1,60 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package commands + +import ( + "context" + "fmt" + "os" + + dfv1 "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" + "github.com/numaproj/numaflow/pkg/shared/logging" + "github.com/numaproj/numaflow/pkg/sideinputs/initializer" + "github.com/spf13/cobra" +) + +func NewSideInputsInitCommand() *cobra.Command { + var ( + isbSvcType string + sideInputsStore string + sideInputs []string + ) + command := &cobra.Command{ + Use: "side-inputs-init", + Short: "Start the Side Inputs init service", + RunE: func(cmd *cobra.Command, args []string) error { + logger := logging.NewLogger().Named("side-inputs-init") + + pipelineName, defined := os.LookupEnv(dfv1.EnvPipelineName) + if !defined { + return fmt.Errorf("environment %q is not defined", dfv1.EnvPipelineName) + } + + if len(sideInputs) == 0 { + return fmt.Errorf("no side inputs are defined for this vertex") + } + + ctx := logging.WithLogger(context.Background(), logger) + sideInputsInitializer := initializer.NewSideInputsInitializer(dfv1.ISBSvcType(isbSvcType), pipelineName, sideInputsStore, sideInputs) + return sideInputsInitializer.Run(ctx) + }, + } + command.Flags().StringVar(&isbSvcType, "isbsvc-type", "jetstream", "ISB Service type, e.g. jetstream") + command.Flags().StringVar(&sideInputsStore, "side-inputs-store", "", "Name of the side inputs store") + command.Flags().StringSliceVar(&sideInputs, "side-inputs", []string{}, "Side Input names") // --side-inputs=si1,si2 --side-inputs=si3 + return command +} diff --git a/cmd/commands/side_inputs_manager.go b/cmd/commands/side_inputs_manager.go new file mode 100644 index 000000000..2d916a2ac --- /dev/null +++ b/cmd/commands/side_inputs_manager.go @@ -0,0 +1,70 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package commands + +import ( + "encoding/base64" + "encoding/json" + "fmt" + "os" + + "github.com/spf13/cobra" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" + + dfv1 "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" + "github.com/numaproj/numaflow/pkg/shared/logging" + "github.com/numaproj/numaflow/pkg/sideinputs/manager" +) + +func NewSideInputsManagerCommand() *cobra.Command { + var ( + isbSvcType string + sideInputsStore string + ) + command := &cobra.Command{ + Use: "side-inputs-manager", + Short: "Start a Side Inputs Manager", + RunE: func(cmd *cobra.Command, args []string) error { + logger := logging.NewLogger().Named("side-inputs-manager") + + encodedSiceInputSpec, defined := os.LookupEnv(dfv1.EnvSideInputObject) + if !defined { + return fmt.Errorf("environment %q is not defined", dfv1.EnvSideInputObject) + } + decodeSideInputBytes, err := base64.StdEncoding.DecodeString(encodedSiceInputSpec) + if err != nil { + return fmt.Errorf("failed to decode encoded SideInput object, error: %w", err) + } + sideInput := &dfv1.SideInput{} + if err = json.Unmarshal(decodeSideInputBytes, sideInput); err != nil { + return fmt.Errorf("failed to unmarshal SideInput object, error: %w", err) + } + + pipelineName, defined := os.LookupEnv(dfv1.EnvPipelineName) + if !defined { + return fmt.Errorf("environment %q is not defined", dfv1.EnvPipelineName) + } + + ctx := logging.WithLogger(signals.SetupSignalHandler(), logger) + sideInputManager := manager.NewSideInputsManager(dfv1.ISBSvcType(isbSvcType), pipelineName, sideInputsStore, sideInput) + return sideInputManager.Start(ctx) + }, + } + command.Flags().StringVar(&isbSvcType, "isbsvc-type", "jetstream", "ISB Service type, e.g. jetstream") + command.Flags().StringVar(&sideInputsStore, "side-inputs-store", "", "Name of the side inputs store") + return command +} diff --git a/cmd/commands/side_inputs_watcher.go b/cmd/commands/side_inputs_watcher.go new file mode 100644 index 000000000..8d1cc01d9 --- /dev/null +++ b/cmd/commands/side_inputs_watcher.go @@ -0,0 +1,61 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package commands + +import ( + "fmt" + "os" + + "github.com/spf13/cobra" + "sigs.k8s.io/controller-runtime/pkg/manager/signals" + + dfv1 "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" + "github.com/numaproj/numaflow/pkg/shared/logging" + "github.com/numaproj/numaflow/pkg/sideinputs/watcher" +) + +func NewSideInputsWatcherCommand() *cobra.Command { + var ( + isbSvcType string + sideInputsStore string + sideInputs []string + ) + command := &cobra.Command{ + Use: "side-inputs-watcher", + Short: "Start the Side Inputs Watcher", + RunE: func(cmd *cobra.Command, args []string) error { + logger := logging.NewLogger().Named("side-inputs-watcher") + + pipelineName, defined := os.LookupEnv(dfv1.EnvPipelineName) + if !defined { + return fmt.Errorf("environment %q is not defined", dfv1.EnvPipelineName) + } + + if len(sideInputs) == 0 { + return fmt.Errorf("no side inputs are defined for this vertex") + } + + ctx := logging.WithLogger(signals.SetupSignalHandler(), logger) + sideInputsWatcher := watcher.NewSideInputsWatcher(dfv1.ISBSvcType(isbSvcType), pipelineName, sideInputsStore, sideInputs) + return sideInputsWatcher.Start(ctx) + }, + } + command.Flags().StringVar(&isbSvcType, "isbsvc-type", "jetstream", "ISB Service type, e.g. jetstream") + command.Flags().StringVar(&sideInputsStore, "side-inputs-store", "", "Name of the side inputs store") + command.Flags().StringSliceVar(&sideInputs, "side-inputs", []string{}, "Side Input names") // --side-inputs=si1,si2 --side-inputs=si3 + return command +} diff --git a/config/base/crds/full/numaflow.numaproj.io_pipelines.yaml b/config/base/crds/full/numaflow.numaproj.io_pipelines.yaml index dfb72489a..db031084a 100644 --- a/config/base/crds/full/numaflow.numaproj.io_pipelines.yaml +++ b/config/base/crds/full/numaflow.numaproj.io_pipelines.yaml @@ -136,6 +136,902 @@ spec: default: 1s type: string type: object + sideInputs: + items: + properties: + container: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + name: + type: string + trigger: + properties: + interval: + type: string + schedule: + type: string + timezone: + type: string + type: object + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - container + - name + - trigger + type: object + type: array templates: properties: daemon: @@ -456,242 +1352,877 @@ spec: type: array matchLabels: additionalProperties: - type: string - type: object - type: object - namespaceSelector: - properties: - matchExpressions: - items: - properties: - key: - type: string - operator: - type: string - values: - items: - type: string - type: array - required: - - key - - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - namespaces: - items: - type: string - type: array - topologyKey: - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - automountServiceAccountToken: - type: boolean - containerTemplate: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - envFrom: - items: - properties: - configMapRef: - properties: - name: - type: string - optional: - type: boolean - type: object - prefix: - type: string - secretRef: - properties: - name: - type: string - optional: - type: boolean - type: object - type: object - type: array - imagePullPolicy: - type: string - resources: - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - capabilities: - properties: - add: - items: - type: string - type: array - drop: - items: - type: string - type: array - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + type: object + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priority: + format: int32 + type: integer + priorityClassName: + type: string + replicas: + format: int32 + type: integer + runtimeClassName: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + job: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array type: object type: object - dnsConfig: - properties: - nameservers: - items: - type: string - type: array - options: - items: - properties: - name: - type: string - value: - type: string - type: object - type: array - searches: - items: - type: string - type: array - type: object - dnsPolicy: - type: string - imagePullSecrets: - items: - properties: - name: - type: string - type: object - type: array - initContainerTemplate: + automountServiceAccountToken: + type: boolean + backoffLimit: + format: int32 + type: integer + containerTemplate: properties: env: items: @@ -857,6 +2388,35 @@ spec: type: object type: object type: object + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array metadata: properties: annotations: @@ -877,9 +2437,6 @@ spec: type: integer priorityClassName: type: string - replicas: - format: int32 - type: integer runtimeClassName: type: string securityContext: @@ -964,8 +2521,11 @@ spec: type: string type: object type: array + ttlSecondsAfterFinished: + format: int32 + type: integer type: object - job: + sideInputsManager: properties: affinity: properties: @@ -1321,12 +2881,204 @@ spec: type: array type: object type: object - automountServiceAccountToken: - type: boolean - backoffLimit: - format: int32 - type: integer - containerTemplate: + automountServiceAccountToken: + type: boolean + containerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + type: object + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainerTemplate: properties: env: items: @@ -1492,35 +3244,6 @@ spec: type: object type: object type: object - dnsConfig: - properties: - nameservers: - items: - type: string - type: array - options: - items: - properties: - name: - type: string - value: - type: string - type: object - type: array - searches: - items: - type: string - type: array - type: object - dnsPolicy: - type: string - imagePullSecrets: - items: - properties: - name: - type: string - type: object - type: array metadata: properties: annotations: @@ -1625,9 +3348,6 @@ spec: type: string type: object type: array - ttlSecondsAfterFinished: - format: int32 - type: integer type: object type: object vertices: @@ -3073,6 +4793,176 @@ spec: type: object serviceAccountName: type: string + sideInputs: + items: + type: string + type: array + sideInputsContainerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + type: object sidecars: items: properties: diff --git a/config/base/crds/full/numaflow.numaproj.io_vertices.yaml b/config/base/crds/full/numaflow.numaproj.io_vertices.yaml index b5cd2f18b..197c41541 100644 --- a/config/base/crds/full/numaflow.numaproj.io_vertices.yaml +++ b/config/base/crds/full/numaflow.numaproj.io_vertices.yaml @@ -1570,6 +1570,176 @@ spec: type: object serviceAccountName: type: string + sideInputs: + items: + type: string + type: array + sideInputsContainerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + type: object sidecars: items: properties: diff --git a/config/install.yaml b/config/install.yaml index 367d631ca..0fb927a86 100644 --- a/config/install.yaml +++ b/config/install.yaml @@ -2581,6 +2581,902 @@ spec: default: 1s type: string type: object + sideInputs: + items: + properties: + container: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + name: + type: string + trigger: + properties: + interval: + type: string + schedule: + type: string + timezone: + type: string + type: object + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - container + - name + - trigger + type: object + type: array templates: properties: daemon: @@ -2920,223 +3816,858 @@ spec: required: - key - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - namespaces: - items: - type: string - type: array - topologyKey: - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - automountServiceAccountToken: - type: boolean - containerTemplate: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - envFrom: - items: - properties: - configMapRef: - properties: - name: - type: string - optional: - type: boolean - type: object - prefix: - type: string - secretRef: - properties: - name: + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + type: object + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priority: + format: int32 + type: integer + priorityClassName: + type: string + replicas: + format: int32 + type: integer + runtimeClassName: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + job: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: type: string - optional: - type: boolean + required: + - topologyKey type: object - type: object - type: array - imagePullPolicy: - type: string - resources: - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - capabilities: - properties: - add: - items: - type: string - type: array - drop: - items: - type: string - type: array - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object + type: array type: object type: object - dnsConfig: - properties: - nameservers: - items: - type: string - type: array - options: - items: - properties: - name: - type: string - value: - type: string - type: object - type: array - searches: - items: - type: string - type: array - type: object - dnsPolicy: - type: string - imagePullSecrets: - items: - properties: - name: - type: string - type: object - type: array - initContainerTemplate: + automountServiceAccountToken: + type: boolean + backoffLimit: + format: int32 + type: integer + containerTemplate: properties: env: items: @@ -3302,6 +4833,35 @@ spec: type: object type: object type: object + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array metadata: properties: annotations: @@ -3322,9 +4882,6 @@ spec: type: integer priorityClassName: type: string - replicas: - format: int32 - type: integer runtimeClassName: type: string securityContext: @@ -3409,8 +4966,11 @@ spec: type: string type: object type: array + ttlSecondsAfterFinished: + format: int32 + type: integer type: object - job: + sideInputsManager: properties: affinity: properties: @@ -3760,18 +5320,210 @@ spec: type: array topologyKey: type: string - required: - - topologyKey + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean type: object - type: array + type: object + type: array + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object type: object type: object - automountServiceAccountToken: - type: boolean - backoffLimit: - format: int32 - type: integer - containerTemplate: + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainerTemplate: properties: env: items: @@ -3937,35 +5689,6 @@ spec: type: object type: object type: object - dnsConfig: - properties: - nameservers: - items: - type: string - type: array - options: - items: - properties: - name: - type: string - value: - type: string - type: object - type: array - searches: - items: - type: string - type: array - type: object - dnsPolicy: - type: string - imagePullSecrets: - items: - properties: - name: - type: string - type: object - type: array metadata: properties: annotations: @@ -4070,9 +5793,6 @@ spec: type: string type: object type: array - ttlSecondsAfterFinished: - format: int32 - type: integer type: object type: object vertices: @@ -5504,20 +7224,190 @@ spec: - value type: object type: array - windowsOptions: + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + sideInputs: + items: + type: string + type: array + sideInputsContainerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + imagePullPolicy: + type: string + resources: properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: type: boolean - runAsUserName: + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object type: object type: object - serviceAccountName: - type: string sidecars: items: properties: @@ -9680,6 +11570,176 @@ spec: type: object serviceAccountName: type: string + sideInputs: + items: + type: string + type: array + sideInputsContainerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + type: object sidecars: items: properties: diff --git a/config/namespace-install.yaml b/config/namespace-install.yaml index 705b2054b..a1b18bec2 100644 --- a/config/namespace-install.yaml +++ b/config/namespace-install.yaml @@ -2581,6 +2581,902 @@ spec: default: 1s type: string type: object + sideInputs: + items: + properties: + container: + properties: + args: + items: + type: string + type: array + command: + items: + type: string + type: array + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + image: + type: string + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + volumeMounts: + items: + properties: + mountPath: + type: string + mountPropagation: + type: string + name: + type: string + readOnly: + type: boolean + subPath: + type: string + subPathExpr: + type: string + required: + - mountPath + - name + type: object + type: array + type: object + name: + type: string + trigger: + properties: + interval: + type: string + schedule: + type: string + timezone: + type: string + type: object + volumes: + items: + properties: + awsElasticBlockStore: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + azureDisk: + properties: + cachingMode: + type: string + diskName: + type: string + diskURI: + type: string + fsType: + type: string + kind: + type: string + readOnly: + type: boolean + required: + - diskName + - diskURI + type: object + azureFile: + properties: + readOnly: + type: boolean + secretName: + type: string + shareName: + type: string + required: + - secretName + - shareName + type: object + cephfs: + properties: + monitors: + items: + type: string + type: array + path: + type: string + readOnly: + type: boolean + secretFile: + type: string + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - monitors + type: object + cinder: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeID: + type: string + required: + - volumeID + type: object + configMap: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + csi: + properties: + driver: + type: string + fsType: + type: string + nodePublishSecretRef: + properties: + name: + type: string + type: object + readOnly: + type: boolean + volumeAttributes: + additionalProperties: + type: string + type: object + required: + - driver + type: object + downwardAPI: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + emptyDir: + properties: + medium: + type: string + sizeLimit: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + ephemeral: + properties: + volumeClaimTemplate: + properties: + metadata: + type: object + spec: + properties: + accessModes: + items: + type: string + type: array + dataSource: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + dataSourceRef: + properties: + apiGroup: + type: string + kind: + type: string + name: + type: string + required: + - kind + - name + type: object + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + selector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + storageClassName: + type: string + volumeMode: + type: string + volumeName: + type: string + type: object + required: + - spec + type: object + type: object + fc: + properties: + fsType: + type: string + lun: + format: int32 + type: integer + readOnly: + type: boolean + targetWWNs: + items: + type: string + type: array + wwids: + items: + type: string + type: array + type: object + flexVolume: + properties: + driver: + type: string + fsType: + type: string + options: + additionalProperties: + type: string + type: object + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + required: + - driver + type: object + flocker: + properties: + datasetName: + type: string + datasetUUID: + type: string + type: object + gcePersistentDisk: + properties: + fsType: + type: string + partition: + format: int32 + type: integer + pdName: + type: string + readOnly: + type: boolean + required: + - pdName + type: object + gitRepo: + properties: + directory: + type: string + repository: + type: string + revision: + type: string + required: + - repository + type: object + glusterfs: + properties: + endpoints: + type: string + path: + type: string + readOnly: + type: boolean + required: + - endpoints + - path + type: object + hostPath: + properties: + path: + type: string + type: + type: string + required: + - path + type: object + iscsi: + properties: + chapAuthDiscovery: + type: boolean + chapAuthSession: + type: boolean + fsType: + type: string + initiatorName: + type: string + iqn: + type: string + iscsiInterface: + type: string + lun: + format: int32 + type: integer + portals: + items: + type: string + type: array + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + targetPortal: + type: string + required: + - iqn + - lun + - targetPortal + type: object + name: + type: string + nfs: + properties: + path: + type: string + readOnly: + type: boolean + server: + type: string + required: + - path + - server + type: object + persistentVolumeClaim: + properties: + claimName: + type: string + readOnly: + type: boolean + required: + - claimName + type: object + photonPersistentDisk: + properties: + fsType: + type: string + pdID: + type: string + required: + - pdID + type: object + portworxVolume: + properties: + fsType: + type: string + readOnly: + type: boolean + volumeID: + type: string + required: + - volumeID + type: object + projected: + properties: + defaultMode: + format: int32 + type: integer + sources: + items: + properties: + configMap: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + downwardAPI: + properties: + items: + items: + properties: + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + mode: + format: int32 + type: integer + path: + type: string + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + required: + - path + type: object + type: array + type: object + secret: + properties: + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + name: + type: string + optional: + type: boolean + type: object + serviceAccountToken: + properties: + audience: + type: string + expirationSeconds: + format: int64 + type: integer + path: + type: string + required: + - path + type: object + type: object + type: array + type: object + quobyte: + properties: + group: + type: string + readOnly: + type: boolean + registry: + type: string + tenant: + type: string + user: + type: string + volume: + type: string + required: + - registry + - volume + type: object + rbd: + properties: + fsType: + type: string + image: + type: string + keyring: + type: string + monitors: + items: + type: string + type: array + pool: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + user: + type: string + required: + - image + - monitors + type: object + scaleIO: + properties: + fsType: + type: string + gateway: + type: string + protectionDomain: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + sslEnabled: + type: boolean + storageMode: + type: string + storagePool: + type: string + system: + type: string + volumeName: + type: string + required: + - gateway + - secretRef + - system + type: object + secret: + properties: + defaultMode: + format: int32 + type: integer + items: + items: + properties: + key: + type: string + mode: + format: int32 + type: integer + path: + type: string + required: + - key + - path + type: object + type: array + optional: + type: boolean + secretName: + type: string + type: object + storageos: + properties: + fsType: + type: string + readOnly: + type: boolean + secretRef: + properties: + name: + type: string + type: object + volumeName: + type: string + volumeNamespace: + type: string + type: object + vsphereVolume: + properties: + fsType: + type: string + storagePolicyID: + type: string + storagePolicyName: + type: string + volumePath: + type: string + required: + - volumePath + type: object + required: + - name + type: object + type: array + required: + - container + - name + - trigger + type: object + type: array templates: properties: daemon: @@ -2920,223 +3816,858 @@ spec: required: - key - operator - type: object - type: array - matchLabels: - additionalProperties: - type: string - type: object - type: object - namespaces: - items: - type: string - type: array - topologyKey: - type: string - required: - - topologyKey - type: object - type: array - type: object - type: object - automountServiceAccountToken: - type: boolean - containerTemplate: - properties: - env: - items: - properties: - name: - type: string - value: - type: string - valueFrom: - properties: - configMapKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - fieldRef: - properties: - apiVersion: - type: string - fieldPath: - type: string - required: - - fieldPath - type: object - resourceFieldRef: - properties: - containerName: - type: string - divisor: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - resource: - type: string - required: - - resource - type: object - secretKeyRef: - properties: - key: - type: string - name: - type: string - optional: - type: boolean - required: - - key - type: object - type: object - required: - - name - type: object - type: array - envFrom: - items: - properties: - configMapRef: - properties: - name: - type: string - optional: - type: boolean - type: object - prefix: - type: string - secretRef: - properties: - name: + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + type: object + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + type: object + metadata: + properties: + annotations: + additionalProperties: + type: string + type: object + labels: + additionalProperties: + type: string + type: object + type: object + nodeSelector: + additionalProperties: + type: string + type: object + priority: + format: int32 + type: integer + priorityClassName: + type: string + replicas: + format: int32 + type: integer + runtimeClassName: + type: string + securityContext: + properties: + fsGroup: + format: int64 + type: integer + fsGroupChangePolicy: + type: string + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + supplementalGroups: + items: + format: int64 + type: integer + type: array + sysctls: + items: + properties: + name: + type: string + value: + type: string + required: + - name + - value + type: object + type: array + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + tolerations: + items: + properties: + effect: + type: string + key: + type: string + operator: + type: string + tolerationSeconds: + format: int64 + type: integer + value: + type: string + type: object + type: array + type: object + job: + properties: + affinity: + properties: + nodeAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + preference: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + weight: + format: int32 + type: integer + required: + - preference + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + properties: + nodeSelectorTerms: + items: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchFields: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + type: object + type: array + required: + - nodeSelectorTerms + type: object + type: object + podAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + type: array + type: object + podAntiAffinity: + properties: + preferredDuringSchedulingIgnoredDuringExecution: + items: + properties: + podAffinityTerm: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: + type: string + required: + - topologyKey + type: object + weight: + format: int32 + type: integer + required: + - podAffinityTerm + - weight + type: object + type: array + requiredDuringSchedulingIgnoredDuringExecution: + items: + properties: + labelSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaceSelector: + properties: + matchExpressions: + items: + properties: + key: + type: string + operator: + type: string + values: + items: + type: string + type: array + required: + - key + - operator + type: object + type: array + matchLabels: + additionalProperties: + type: string + type: object + type: object + namespaces: + items: + type: string + type: array + topologyKey: type: string - optional: - type: boolean + required: + - topologyKey type: object - type: object - type: array - imagePullPolicy: - type: string - resources: - properties: - limits: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - requests: - additionalProperties: - anyOf: - - type: integer - - type: string - pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ - x-kubernetes-int-or-string: true - type: object - type: object - securityContext: - properties: - allowPrivilegeEscalation: - type: boolean - capabilities: - properties: - add: - items: - type: string - type: array - drop: - items: - type: string - type: array - type: object - privileged: - type: boolean - procMount: - type: string - readOnlyRootFilesystem: - type: boolean - runAsGroup: - format: int64 - type: integer - runAsNonRoot: - type: boolean - runAsUser: - format: int64 - type: integer - seLinuxOptions: - properties: - level: - type: string - role: - type: string - type: - type: string - user: - type: string - type: object - seccompProfile: - properties: - localhostProfile: - type: string - type: - type: string - required: - - type - type: object - windowsOptions: - properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: - type: boolean - runAsUserName: - type: string - type: object + type: array type: object type: object - dnsConfig: - properties: - nameservers: - items: - type: string - type: array - options: - items: - properties: - name: - type: string - value: - type: string - type: object - type: array - searches: - items: - type: string - type: array - type: object - dnsPolicy: - type: string - imagePullSecrets: - items: - properties: - name: - type: string - type: object - type: array - initContainerTemplate: + automountServiceAccountToken: + type: boolean + backoffLimit: + format: int32 + type: integer + containerTemplate: properties: env: items: @@ -3302,6 +4833,35 @@ spec: type: object type: object type: object + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array metadata: properties: annotations: @@ -3322,9 +4882,6 @@ spec: type: integer priorityClassName: type: string - replicas: - format: int32 - type: integer runtimeClassName: type: string securityContext: @@ -3409,8 +4966,11 @@ spec: type: string type: object type: array + ttlSecondsAfterFinished: + format: int32 + type: integer type: object - job: + sideInputsManager: properties: affinity: properties: @@ -3760,18 +5320,210 @@ spec: type: array topologyKey: type: string - required: - - topologyKey + required: + - topologyKey + type: object + type: array + type: object + type: object + automountServiceAccountToken: + type: boolean + containerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean type: object - type: array + type: object + type: array + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object type: object type: object - automountServiceAccountToken: - type: boolean - backoffLimit: - format: int32 - type: integer - containerTemplate: + dnsConfig: + properties: + nameservers: + items: + type: string + type: array + options: + items: + properties: + name: + type: string + value: + type: string + type: object + type: array + searches: + items: + type: string + type: array + type: object + dnsPolicy: + type: string + imagePullSecrets: + items: + properties: + name: + type: string + type: object + type: array + initContainerTemplate: properties: env: items: @@ -3937,35 +5689,6 @@ spec: type: object type: object type: object - dnsConfig: - properties: - nameservers: - items: - type: string - type: array - options: - items: - properties: - name: - type: string - value: - type: string - type: object - type: array - searches: - items: - type: string - type: array - type: object - dnsPolicy: - type: string - imagePullSecrets: - items: - properties: - name: - type: string - type: object - type: array metadata: properties: annotations: @@ -4070,9 +5793,6 @@ spec: type: string type: object type: array - ttlSecondsAfterFinished: - format: int32 - type: integer type: object type: object vertices: @@ -5504,20 +7224,190 @@ spec: - value type: object type: array - windowsOptions: + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + serviceAccountName: + type: string + sideInputs: + items: + type: string + type: array + sideInputsContainerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + imagePullPolicy: + type: string + resources: properties: - gmsaCredentialSpec: - type: string - gmsaCredentialSpecName: - type: string - hostProcess: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: type: boolean - runAsUserName: + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object type: object type: object - serviceAccountName: - type: string sidecars: items: properties: @@ -9680,6 +11570,176 @@ spec: type: object serviceAccountName: type: string + sideInputs: + items: + type: string + type: array + sideInputsContainerTemplate: + properties: + env: + items: + properties: + name: + type: string + value: + type: string + valueFrom: + properties: + configMapKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + fieldRef: + properties: + apiVersion: + type: string + fieldPath: + type: string + required: + - fieldPath + type: object + resourceFieldRef: + properties: + containerName: + type: string + divisor: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + resource: + type: string + required: + - resource + type: object + secretKeyRef: + properties: + key: + type: string + name: + type: string + optional: + type: boolean + required: + - key + type: object + type: object + required: + - name + type: object + type: array + envFrom: + items: + properties: + configMapRef: + properties: + name: + type: string + optional: + type: boolean + type: object + prefix: + type: string + secretRef: + properties: + name: + type: string + optional: + type: boolean + type: object + type: object + type: array + imagePullPolicy: + type: string + resources: + properties: + limits: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + requests: + additionalProperties: + anyOf: + - type: integer + - type: string + pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ + x-kubernetes-int-or-string: true + type: object + type: object + securityContext: + properties: + allowPrivilegeEscalation: + type: boolean + capabilities: + properties: + add: + items: + type: string + type: array + drop: + items: + type: string + type: array + type: object + privileged: + type: boolean + procMount: + type: string + readOnlyRootFilesystem: + type: boolean + runAsGroup: + format: int64 + type: integer + runAsNonRoot: + type: boolean + runAsUser: + format: int64 + type: integer + seLinuxOptions: + properties: + level: + type: string + role: + type: string + type: + type: string + user: + type: string + type: object + seccompProfile: + properties: + localhostProfile: + type: string + type: + type: string + required: + - type + type: object + windowsOptions: + properties: + gmsaCredentialSpec: + type: string + gmsaCredentialSpecName: + type: string + hostProcess: + type: boolean + runAsUserName: + type: string + type: object + type: object + type: object sidecars: items: properties: diff --git a/docs/APIs.md b/docs/APIs.md index 34a535467..348e85093 100644 --- a/docs/APIs.md +++ b/docs/APIs.md @@ -23,7 +23,8 @@ AbstractPodTemplate DaemonTemplate, JetStreamBufferService, JobTemplate, -NativeRedis) +NativeRedis, +SideInputsManagerTemplate)

@@ -298,6 +299,9 @@ ContainerTemplate (Optional) +

+Container template for the main numa container. +

@@ -308,6 +312,10 @@ ContainerTemplate (Optional) +

+Container template for all the vertex pod init containers spawned by +numaflow, excluding the ones specified by the user. +

@@ -369,7 +377,7 @@ Settings for autoscaling (Optional)

-List of init containers belonging to the pod. More info: +List of customized init containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/

@@ -383,7 +391,7 @@ List of init containers belonging to the pod. More info: (Optional)

-List of sidecar containers belonging to the pod. +List of customized sidecar containers belonging to the pod.

@@ -399,6 +407,30 @@ sink vertices only.

+ + +sideInputs
\[\]string + + +(Optional) +

+Names of the side inputs used in this vertex. +

+ + + + +sideInputsContainerTemplate
+ +ContainerTemplate + + +(Optional) +

+Container template for the side inputs watcher container. +

+ +

@@ -678,6 +710,7 @@ Container

(Appears on: +SideInput, UDF, UDSink, UDTransformer) @@ -795,7 +828,8 @@ ContainerTemplate DaemonTemplate, JetStreamBufferService, JobTemplate, -NativeRedis) +NativeRedis, +SideInputsManagerTemplate)

@@ -1684,6 +1718,59 @@ Description +

+GetSideInputDeploymentReq +

+

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+Field + +Description +
+ISBSvcType
+ ISBSvcType + +
+
+Image
string +
+
+PullPolicy
+ +Kubernetes core/v1.PullPolicy +
+
+Env
+ +\[\]Kubernetes core/v1.EnvVar +
+

GetVertexPodSpecReq

@@ -1735,6 +1822,13 @@ Kubernetes core/v1.PullPolicy + + +SideInputsStoreName
string + + + +

@@ -1870,6 +1964,7 @@ ISBSvcType (string alias)

(Appears on: GetDaemonDeploymentReq, +GetSideInputDeploymentReq, GetVertexPodSpecReq, InterStepBufferServiceStatus)

@@ -3149,6 +3244,19 @@ for the Pipeline

+ + +sideInputs
+ \[\]SideInput + + + +(Optional) +

+SideInputs defines the Side Inputs of a pipeline. +

+ + @@ -3193,7 +3301,7 @@ Description (Optional)

Read batch size for all the vertices in the pipeline, can be overridden -by the vertex’s limit settings +by the vertex’s limit settings.

@@ -3204,7 +3312,7 @@ by the vertex’s limit settings (Optional)

-BufferMaxLength is used to define the max length of a buffer Only +BufferMaxLength is used to define the max length of a buffer. Only applies to UDF and Source vertices as only they do buffer write. It can be overridden by the settings in vertex limits.

@@ -3352,6 +3460,19 @@ for the Pipeline

+ + +sideInputs
+ \[\]SideInput + + + +(Optional) +

+SideInputs defines the Side Inputs of a pipeline. +

+ +

@@ -3990,6 +4111,178 @@ once. The is use to prevent too aggressive scaling operations +

+SideInput +

+

+(Appears on: +PipelineSpec) +

+

+

+SideInput defines information of a Side Input +

+

+ + + + + + + + + + + + + + + + + + + + + + + + + +
+Field + +Description +
+name
string +
+
+container
+ Container +
+
+volumes
+ +\[\]Kubernetes core/v1.Volume +
+(Optional) +
+trigger
+ +SideInputTrigger +
+
+

+SideInputTrigger +

+

+(Appears on: +SideInput) +

+

+

+ + + + + + + + + + + + + + + + + + + + + +
+Field + +Description +
+schedule
string +
+(Optional) +
+interval
+ +Kubernetes meta/v1.Duration +
+(Optional) +
+timezone
string +
+(Optional) +
+

+SideInputsManagerTemplate +

+

+(Appears on: +Templates) +

+

+

+ + + + + + + + + + + + + + + + + + + + + +
+Field + +Description +
+AbstractPodTemplate
+ +AbstractPodTemplate +
+

+(Members of AbstractPodTemplate are embedded into this +type.) +

+(Optional) +
+containerTemplate
+ +ContainerTemplate +
+(Optional) +

+Template for the side inputs manager numa container +

+
+initContainerTemplate
+ +ContainerTemplate +
+(Optional) +

+Template for the side inputs manager init container +

+

Sink

@@ -4363,7 +4656,7 @@ Description (Optional)

-DaemonTemplate is used to customize the Daemon Deployment +DaemonTemplate is used to customize the Daemon Deployment.

@@ -4376,7 +4669,20 @@ DaemonTemplate is used to customize the Daemon Deployment (Optional)

-JobTemplate is used to customize Jobs +JobTemplate is used to customize Jobs. +

+ + + + +sideInputsManager
+ +SideInputsManagerTemplate + + +(Optional) +

+SideInputsManagerTemplate is used to customize the Side Inputs Manager.

diff --git a/docs/specifications/side-inputs.md b/docs/specifications/side-inputs.md index 539f7ae08..16bc04408 100644 --- a/docs/specifications/side-inputs.md +++ b/docs/specifications/side-inputs.md @@ -88,7 +88,7 @@ Some new features will be added to the Numaflow SDK. RetrieveSideInput() ([]bytes, error) ``` -- A main function to start the service in the Side Input Manager user container. +- A main function to start the service in the Side Inputs Manager user container. - A helper function to be used in the udf/udsink/transformer containers to get the Side Inputs, which reads, watches and caches the data from the shared volume. ```go diff --git a/pkg/apis/numaflow/v1alpha1/const.go b/pkg/apis/numaflow/v1alpha1/const.go index f6fff8b03..570f3b3c5 100644 --- a/pkg/apis/numaflow/v1alpha1/const.go +++ b/pkg/apis/numaflow/v1alpha1/const.go @@ -38,6 +38,7 @@ const ( KeyPipelineName = "numaflow.numaproj.io/pipeline-name" KeyVertexName = "numaflow.numaproj.io/vertex-name" KeyReplica = "numaflow.numaproj.io/replica" + KeySideInputName = "numaflow.numaproj.io/side-input-name" KeyDefaultContainer = "kubectl.kubernetes.io/default-container" // ID key in the header of sources like http @@ -62,23 +63,26 @@ const ( JetStreamConfigMapKey = "nats-js" // key for nats-js.conf in the configmap // container names. - CtrInit = "init" - CtrMain = "numa" - CtrUdf = "udf" - CtrUdsink = "udsink" - CtrUdtransformer = "transformer" + CtrInit = "init" + CtrMain = "numa" + CtrUdf = "udf" + CtrUdsink = "udsink" + CtrUdtransformer = "transformer" + CtrUdSideInput = "udsi" + CtrInitSideInputs = "init-side-inputs" + CtrSideInputsWatcher = "side-inputs-watcher" // components - ComponentISBSvc = "isbsvc" - ComponentDaemon = "daemon" - ComponentVertex = "vertex" - ComponentJob = "job" + ComponentISBSvc = "isbsvc" + ComponentDaemon = "daemon" + ComponentVertex = "vertex" + ComponentJob = "job" + ComponentSideInputManager = "side-inputs-manager" // controllers ControllerISBSvc = "isbsvc-controller" ControllerPipeline = "pipeline-controller" ControllerVertex = "vertex-controller" - ControllerWatchdog = "watchdog" // ENV vars EnvNamespace = "NUMAFLOW_NAMESPACE" @@ -88,6 +92,7 @@ const ( EnvReplica = "NUMAFLOW_REPLICA" EnvVertexObject = "NUMAFLOW_VERTEX_OBJECT" EnvPipelineObject = "NUMAFLOW_PIPELINE_OBJECT" + EnvSideInputObject = "NUMAFLOW_SIDE_INPUT_OBJECT" EnvImage = "NUMAFLOW_IMAGE" EnvImagePullPolicy = "NUMAFLOW_IMAGE_PULL_POLICY" EnvISBSvcRedisSentinelURL = "NUMAFLOW_ISBSVC_REDIS_SENTINEL_URL" @@ -111,6 +116,7 @@ const ( EnvCPULimit = "NUMAFLOW_CPU_LIMIT" EnvMemoryRequest = "NUMAFLOW_MEMORY_REQUEST" EnvMemoryLimit = "NUMAFLOW_MEMORY_LIMIT" + EnvGoDebug = "GODEBUG" PathVarRun = "/var/run/numaflow" VertexMetricsPort = 2469 @@ -121,6 +127,8 @@ const ( DefaultRequeueAfter = 10 * time.Second + PathSideInputsMount = "/var/numaflow/side-inputs" + // ISB DefaultBufferLength = 30000 DefaultBufferUsageLimit = 0.8 diff --git a/pkg/apis/numaflow/v1alpha1/container_template.go b/pkg/apis/numaflow/v1alpha1/container_template.go index 04613fda9..071229114 100644 --- a/pkg/apis/numaflow/v1alpha1/container_template.go +++ b/pkg/apis/numaflow/v1alpha1/container_template.go @@ -53,7 +53,7 @@ func (ct *ContainerTemplate) ApplyToContainer(c *corev1.Container) { // ApplyToNumaflowContainers updates any numa or init containers with the values from the ContainerTemplate func (ct *ContainerTemplate) ApplyToNumaflowContainers(containers []corev1.Container) { for i := range containers { - if containers[i].Name == CtrMain || containers[i].Name == CtrInit { + if containers[i].Name == CtrMain || containers[i].Name == CtrInit || containers[i].Name == CtrInitSideInputs { ct.ApplyToContainer(&containers[i]) } } diff --git a/pkg/apis/numaflow/v1alpha1/generated.pb.go b/pkg/apis/numaflow/v1alpha1/generated.pb.go index c4eb92391..3266c6cba 100644 --- a/pkg/apis/numaflow/v1alpha1/generated.pb.go +++ b/pkg/apis/numaflow/v1alpha1/generated.pb.go @@ -636,10 +636,38 @@ func (m *GetRedisStatefulSetSpecReq) XXX_DiscardUnknown() { var xxx_messageInfo_GetRedisStatefulSetSpecReq proto.InternalMessageInfo +func (m *GetSideInputDeploymentReq) Reset() { *m = GetSideInputDeploymentReq{} } +func (*GetSideInputDeploymentReq) ProtoMessage() {} +func (*GetSideInputDeploymentReq) Descriptor() ([]byte, []int) { + return fileDescriptor_9d0d1b17d3865563, []int{21} +} +func (m *GetSideInputDeploymentReq) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *GetSideInputDeploymentReq) 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 *GetSideInputDeploymentReq) XXX_Merge(src proto.Message) { + xxx_messageInfo_GetSideInputDeploymentReq.Merge(m, src) +} +func (m *GetSideInputDeploymentReq) XXX_Size() int { + return m.Size() +} +func (m *GetSideInputDeploymentReq) XXX_DiscardUnknown() { + xxx_messageInfo_GetSideInputDeploymentReq.DiscardUnknown(m) +} + +var xxx_messageInfo_GetSideInputDeploymentReq proto.InternalMessageInfo + func (m *GetVertexPodSpecReq) Reset() { *m = GetVertexPodSpecReq{} } func (*GetVertexPodSpecReq) ProtoMessage() {} func (*GetVertexPodSpecReq) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{21} + return fileDescriptor_9d0d1b17d3865563, []int{22} } func (m *GetVertexPodSpecReq) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -667,7 +695,7 @@ var xxx_messageInfo_GetVertexPodSpecReq proto.InternalMessageInfo func (m *GroupBy) Reset() { *m = GroupBy{} } func (*GroupBy) ProtoMessage() {} func (*GroupBy) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{22} + return fileDescriptor_9d0d1b17d3865563, []int{23} } func (m *GroupBy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -695,7 +723,7 @@ var xxx_messageInfo_GroupBy proto.InternalMessageInfo func (m *HTTPSource) Reset() { *m = HTTPSource{} } func (*HTTPSource) ProtoMessage() {} func (*HTTPSource) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{23} + return fileDescriptor_9d0d1b17d3865563, []int{24} } func (m *HTTPSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -723,7 +751,7 @@ var xxx_messageInfo_HTTPSource proto.InternalMessageInfo func (m *InterStepBufferService) Reset() { *m = InterStepBufferService{} } func (*InterStepBufferService) ProtoMessage() {} func (*InterStepBufferService) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{24} + return fileDescriptor_9d0d1b17d3865563, []int{25} } func (m *InterStepBufferService) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -751,7 +779,7 @@ var xxx_messageInfo_InterStepBufferService proto.InternalMessageInfo func (m *InterStepBufferServiceList) Reset() { *m = InterStepBufferServiceList{} } func (*InterStepBufferServiceList) ProtoMessage() {} func (*InterStepBufferServiceList) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{25} + return fileDescriptor_9d0d1b17d3865563, []int{26} } func (m *InterStepBufferServiceList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -779,7 +807,7 @@ var xxx_messageInfo_InterStepBufferServiceList proto.InternalMessageInfo func (m *InterStepBufferServiceSpec) Reset() { *m = InterStepBufferServiceSpec{} } func (*InterStepBufferServiceSpec) ProtoMessage() {} func (*InterStepBufferServiceSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{26} + return fileDescriptor_9d0d1b17d3865563, []int{27} } func (m *InterStepBufferServiceSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -807,7 +835,7 @@ var xxx_messageInfo_InterStepBufferServiceSpec proto.InternalMessageInfo func (m *InterStepBufferServiceStatus) Reset() { *m = InterStepBufferServiceStatus{} } func (*InterStepBufferServiceStatus) ProtoMessage() {} func (*InterStepBufferServiceStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{27} + return fileDescriptor_9d0d1b17d3865563, []int{28} } func (m *InterStepBufferServiceStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -835,7 +863,7 @@ var xxx_messageInfo_InterStepBufferServiceStatus proto.InternalMessageInfo func (m *JetStreamBufferService) Reset() { *m = JetStreamBufferService{} } func (*JetStreamBufferService) ProtoMessage() {} func (*JetStreamBufferService) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{28} + return fileDescriptor_9d0d1b17d3865563, []int{29} } func (m *JetStreamBufferService) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -863,7 +891,7 @@ var xxx_messageInfo_JetStreamBufferService proto.InternalMessageInfo func (m *JetStreamConfig) Reset() { *m = JetStreamConfig{} } func (*JetStreamConfig) ProtoMessage() {} func (*JetStreamConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{29} + return fileDescriptor_9d0d1b17d3865563, []int{30} } func (m *JetStreamConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -891,7 +919,7 @@ var xxx_messageInfo_JetStreamConfig proto.InternalMessageInfo func (m *JobTemplate) Reset() { *m = JobTemplate{} } func (*JobTemplate) ProtoMessage() {} func (*JobTemplate) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{30} + return fileDescriptor_9d0d1b17d3865563, []int{31} } func (m *JobTemplate) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -919,7 +947,7 @@ var xxx_messageInfo_JobTemplate proto.InternalMessageInfo func (m *KafkaSink) Reset() { *m = KafkaSink{} } func (*KafkaSink) ProtoMessage() {} func (*KafkaSink) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{31} + return fileDescriptor_9d0d1b17d3865563, []int{32} } func (m *KafkaSink) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -947,7 +975,7 @@ var xxx_messageInfo_KafkaSink proto.InternalMessageInfo func (m *KafkaSource) Reset() { *m = KafkaSource{} } func (*KafkaSource) ProtoMessage() {} func (*KafkaSource) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{32} + return fileDescriptor_9d0d1b17d3865563, []int{33} } func (m *KafkaSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -975,7 +1003,7 @@ var xxx_messageInfo_KafkaSource proto.InternalMessageInfo func (m *Lifecycle) Reset() { *m = Lifecycle{} } func (*Lifecycle) ProtoMessage() {} func (*Lifecycle) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{33} + return fileDescriptor_9d0d1b17d3865563, []int{34} } func (m *Lifecycle) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1003,7 +1031,7 @@ var xxx_messageInfo_Lifecycle proto.InternalMessageInfo func (m *Log) Reset() { *m = Log{} } func (*Log) ProtoMessage() {} func (*Log) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{34} + return fileDescriptor_9d0d1b17d3865563, []int{35} } func (m *Log) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1031,7 +1059,7 @@ var xxx_messageInfo_Log proto.InternalMessageInfo func (m *Metadata) Reset() { *m = Metadata{} } func (*Metadata) ProtoMessage() {} func (*Metadata) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{35} + return fileDescriptor_9d0d1b17d3865563, []int{36} } func (m *Metadata) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1059,7 +1087,7 @@ var xxx_messageInfo_Metadata proto.InternalMessageInfo func (m *NativeRedis) Reset() { *m = NativeRedis{} } func (*NativeRedis) ProtoMessage() {} func (*NativeRedis) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{36} + return fileDescriptor_9d0d1b17d3865563, []int{37} } func (m *NativeRedis) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1087,7 +1115,7 @@ var xxx_messageInfo_NativeRedis proto.InternalMessageInfo func (m *NatsAuth) Reset() { *m = NatsAuth{} } func (*NatsAuth) ProtoMessage() {} func (*NatsAuth) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{37} + return fileDescriptor_9d0d1b17d3865563, []int{38} } func (m *NatsAuth) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1115,7 +1143,7 @@ var xxx_messageInfo_NatsAuth proto.InternalMessageInfo func (m *NatsSource) Reset() { *m = NatsSource{} } func (*NatsSource) ProtoMessage() {} func (*NatsSource) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{38} + return fileDescriptor_9d0d1b17d3865563, []int{39} } func (m *NatsSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1143,7 +1171,7 @@ var xxx_messageInfo_NatsSource proto.InternalMessageInfo func (m *PBQStorage) Reset() { *m = PBQStorage{} } func (*PBQStorage) ProtoMessage() {} func (*PBQStorage) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{39} + return fileDescriptor_9d0d1b17d3865563, []int{40} } func (m *PBQStorage) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1171,7 +1199,7 @@ var xxx_messageInfo_PBQStorage proto.InternalMessageInfo func (m *PersistenceStrategy) Reset() { *m = PersistenceStrategy{} } func (*PersistenceStrategy) ProtoMessage() {} func (*PersistenceStrategy) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{40} + return fileDescriptor_9d0d1b17d3865563, []int{41} } func (m *PersistenceStrategy) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1199,7 +1227,7 @@ var xxx_messageInfo_PersistenceStrategy proto.InternalMessageInfo func (m *Pipeline) Reset() { *m = Pipeline{} } func (*Pipeline) ProtoMessage() {} func (*Pipeline) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{41} + return fileDescriptor_9d0d1b17d3865563, []int{42} } func (m *Pipeline) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1227,7 +1255,7 @@ var xxx_messageInfo_Pipeline proto.InternalMessageInfo func (m *PipelineLimits) Reset() { *m = PipelineLimits{} } func (*PipelineLimits) ProtoMessage() {} func (*PipelineLimits) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{42} + return fileDescriptor_9d0d1b17d3865563, []int{43} } func (m *PipelineLimits) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1255,7 +1283,7 @@ var xxx_messageInfo_PipelineLimits proto.InternalMessageInfo func (m *PipelineList) Reset() { *m = PipelineList{} } func (*PipelineList) ProtoMessage() {} func (*PipelineList) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{43} + return fileDescriptor_9d0d1b17d3865563, []int{44} } func (m *PipelineList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1283,7 +1311,7 @@ var xxx_messageInfo_PipelineList proto.InternalMessageInfo func (m *PipelineSpec) Reset() { *m = PipelineSpec{} } func (*PipelineSpec) ProtoMessage() {} func (*PipelineSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{44} + return fileDescriptor_9d0d1b17d3865563, []int{45} } func (m *PipelineSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1311,7 +1339,7 @@ var xxx_messageInfo_PipelineSpec proto.InternalMessageInfo func (m *PipelineStatus) Reset() { *m = PipelineStatus{} } func (*PipelineStatus) ProtoMessage() {} func (*PipelineStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{45} + return fileDescriptor_9d0d1b17d3865563, []int{46} } func (m *PipelineStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1339,7 +1367,7 @@ var xxx_messageInfo_PipelineStatus proto.InternalMessageInfo func (m *RedisBufferService) Reset() { *m = RedisBufferService{} } func (*RedisBufferService) ProtoMessage() {} func (*RedisBufferService) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{46} + return fileDescriptor_9d0d1b17d3865563, []int{47} } func (m *RedisBufferService) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1367,7 +1395,7 @@ var xxx_messageInfo_RedisBufferService proto.InternalMessageInfo func (m *RedisConfig) Reset() { *m = RedisConfig{} } func (*RedisConfig) ProtoMessage() {} func (*RedisConfig) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{47} + return fileDescriptor_9d0d1b17d3865563, []int{48} } func (m *RedisConfig) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1395,7 +1423,7 @@ var xxx_messageInfo_RedisConfig proto.InternalMessageInfo func (m *RedisSettings) Reset() { *m = RedisSettings{} } func (*RedisSettings) ProtoMessage() {} func (*RedisSettings) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{48} + return fileDescriptor_9d0d1b17d3865563, []int{49} } func (m *RedisSettings) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1423,7 +1451,7 @@ var xxx_messageInfo_RedisSettings proto.InternalMessageInfo func (m *RedisStreamsSource) Reset() { *m = RedisStreamsSource{} } func (*RedisStreamsSource) ProtoMessage() {} func (*RedisStreamsSource) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{49} + return fileDescriptor_9d0d1b17d3865563, []int{50} } func (m *RedisStreamsSource) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1451,7 +1479,7 @@ var xxx_messageInfo_RedisStreamsSource proto.InternalMessageInfo func (m *SASL) Reset() { *m = SASL{} } func (*SASL) ProtoMessage() {} func (*SASL) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{50} + return fileDescriptor_9d0d1b17d3865563, []int{51} } func (m *SASL) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1479,7 +1507,7 @@ var xxx_messageInfo_SASL proto.InternalMessageInfo func (m *SASLPlain) Reset() { *m = SASLPlain{} } func (*SASLPlain) ProtoMessage() {} func (*SASLPlain) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{51} + return fileDescriptor_9d0d1b17d3865563, []int{52} } func (m *SASLPlain) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1507,7 +1535,7 @@ var xxx_messageInfo_SASLPlain proto.InternalMessageInfo func (m *Scale) Reset() { *m = Scale{} } func (*Scale) ProtoMessage() {} func (*Scale) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{52} + return fileDescriptor_9d0d1b17d3865563, []int{53} } func (m *Scale) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1532,10 +1560,94 @@ func (m *Scale) XXX_DiscardUnknown() { var xxx_messageInfo_Scale proto.InternalMessageInfo +func (m *SideInput) Reset() { *m = SideInput{} } +func (*SideInput) ProtoMessage() {} +func (*SideInput) Descriptor() ([]byte, []int) { + return fileDescriptor_9d0d1b17d3865563, []int{54} +} +func (m *SideInput) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SideInput) 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 *SideInput) XXX_Merge(src proto.Message) { + xxx_messageInfo_SideInput.Merge(m, src) +} +func (m *SideInput) XXX_Size() int { + return m.Size() +} +func (m *SideInput) XXX_DiscardUnknown() { + xxx_messageInfo_SideInput.DiscardUnknown(m) +} + +var xxx_messageInfo_SideInput proto.InternalMessageInfo + +func (m *SideInputTrigger) Reset() { *m = SideInputTrigger{} } +func (*SideInputTrigger) ProtoMessage() {} +func (*SideInputTrigger) Descriptor() ([]byte, []int) { + return fileDescriptor_9d0d1b17d3865563, []int{55} +} +func (m *SideInputTrigger) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SideInputTrigger) 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 *SideInputTrigger) XXX_Merge(src proto.Message) { + xxx_messageInfo_SideInputTrigger.Merge(m, src) +} +func (m *SideInputTrigger) XXX_Size() int { + return m.Size() +} +func (m *SideInputTrigger) XXX_DiscardUnknown() { + xxx_messageInfo_SideInputTrigger.DiscardUnknown(m) +} + +var xxx_messageInfo_SideInputTrigger proto.InternalMessageInfo + +func (m *SideInputsManagerTemplate) Reset() { *m = SideInputsManagerTemplate{} } +func (*SideInputsManagerTemplate) ProtoMessage() {} +func (*SideInputsManagerTemplate) Descriptor() ([]byte, []int) { + return fileDescriptor_9d0d1b17d3865563, []int{56} +} +func (m *SideInputsManagerTemplate) XXX_Unmarshal(b []byte) error { + return m.Unmarshal(b) +} +func (m *SideInputsManagerTemplate) 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 *SideInputsManagerTemplate) XXX_Merge(src proto.Message) { + xxx_messageInfo_SideInputsManagerTemplate.Merge(m, src) +} +func (m *SideInputsManagerTemplate) XXX_Size() int { + return m.Size() +} +func (m *SideInputsManagerTemplate) XXX_DiscardUnknown() { + xxx_messageInfo_SideInputsManagerTemplate.DiscardUnknown(m) +} + +var xxx_messageInfo_SideInputsManagerTemplate proto.InternalMessageInfo + func (m *Sink) Reset() { *m = Sink{} } func (*Sink) ProtoMessage() {} func (*Sink) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{53} + return fileDescriptor_9d0d1b17d3865563, []int{57} } func (m *Sink) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1563,7 +1675,7 @@ var xxx_messageInfo_Sink proto.InternalMessageInfo func (m *SlidingWindow) Reset() { *m = SlidingWindow{} } func (*SlidingWindow) ProtoMessage() {} func (*SlidingWindow) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{54} + return fileDescriptor_9d0d1b17d3865563, []int{58} } func (m *SlidingWindow) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1591,7 +1703,7 @@ var xxx_messageInfo_SlidingWindow proto.InternalMessageInfo func (m *Source) Reset() { *m = Source{} } func (*Source) ProtoMessage() {} func (*Source) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{55} + return fileDescriptor_9d0d1b17d3865563, []int{59} } func (m *Source) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1619,7 +1731,7 @@ var xxx_messageInfo_Source proto.InternalMessageInfo func (m *Status) Reset() { *m = Status{} } func (*Status) ProtoMessage() {} func (*Status) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{56} + return fileDescriptor_9d0d1b17d3865563, []int{60} } func (m *Status) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1647,7 +1759,7 @@ var xxx_messageInfo_Status proto.InternalMessageInfo func (m *TLS) Reset() { *m = TLS{} } func (*TLS) ProtoMessage() {} func (*TLS) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{57} + return fileDescriptor_9d0d1b17d3865563, []int{61} } func (m *TLS) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1675,7 +1787,7 @@ var xxx_messageInfo_TLS proto.InternalMessageInfo func (m *TagConditions) Reset() { *m = TagConditions{} } func (*TagConditions) ProtoMessage() {} func (*TagConditions) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{58} + return fileDescriptor_9d0d1b17d3865563, []int{62} } func (m *TagConditions) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1703,7 +1815,7 @@ var xxx_messageInfo_TagConditions proto.InternalMessageInfo func (m *Templates) Reset() { *m = Templates{} } func (*Templates) ProtoMessage() {} func (*Templates) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{59} + return fileDescriptor_9d0d1b17d3865563, []int{63} } func (m *Templates) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1731,7 +1843,7 @@ var xxx_messageInfo_Templates proto.InternalMessageInfo func (m *Transformer) Reset() { *m = Transformer{} } func (*Transformer) ProtoMessage() {} func (*Transformer) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{60} + return fileDescriptor_9d0d1b17d3865563, []int{64} } func (m *Transformer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1759,7 +1871,7 @@ var xxx_messageInfo_Transformer proto.InternalMessageInfo func (m *UDF) Reset() { *m = UDF{} } func (*UDF) ProtoMessage() {} func (*UDF) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{61} + return fileDescriptor_9d0d1b17d3865563, []int{65} } func (m *UDF) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1787,7 +1899,7 @@ var xxx_messageInfo_UDF proto.InternalMessageInfo func (m *UDSink) Reset() { *m = UDSink{} } func (*UDSink) ProtoMessage() {} func (*UDSink) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{62} + return fileDescriptor_9d0d1b17d3865563, []int{66} } func (m *UDSink) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1815,7 +1927,7 @@ var xxx_messageInfo_UDSink proto.InternalMessageInfo func (m *UDTransformer) Reset() { *m = UDTransformer{} } func (*UDTransformer) ProtoMessage() {} func (*UDTransformer) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{63} + return fileDescriptor_9d0d1b17d3865563, []int{67} } func (m *UDTransformer) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1843,7 +1955,7 @@ var xxx_messageInfo_UDTransformer proto.InternalMessageInfo func (m *Vertex) Reset() { *m = Vertex{} } func (*Vertex) ProtoMessage() {} func (*Vertex) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{64} + return fileDescriptor_9d0d1b17d3865563, []int{68} } func (m *Vertex) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1871,7 +1983,7 @@ var xxx_messageInfo_Vertex proto.InternalMessageInfo func (m *VertexInstance) Reset() { *m = VertexInstance{} } func (*VertexInstance) ProtoMessage() {} func (*VertexInstance) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{65} + return fileDescriptor_9d0d1b17d3865563, []int{69} } func (m *VertexInstance) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1899,7 +2011,7 @@ var xxx_messageInfo_VertexInstance proto.InternalMessageInfo func (m *VertexLimits) Reset() { *m = VertexLimits{} } func (*VertexLimits) ProtoMessage() {} func (*VertexLimits) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{66} + return fileDescriptor_9d0d1b17d3865563, []int{70} } func (m *VertexLimits) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1927,7 +2039,7 @@ var xxx_messageInfo_VertexLimits proto.InternalMessageInfo func (m *VertexList) Reset() { *m = VertexList{} } func (*VertexList) ProtoMessage() {} func (*VertexList) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{67} + return fileDescriptor_9d0d1b17d3865563, []int{71} } func (m *VertexList) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1955,7 +2067,7 @@ var xxx_messageInfo_VertexList proto.InternalMessageInfo func (m *VertexSpec) Reset() { *m = VertexSpec{} } func (*VertexSpec) ProtoMessage() {} func (*VertexSpec) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{68} + return fileDescriptor_9d0d1b17d3865563, []int{72} } func (m *VertexSpec) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -1983,7 +2095,7 @@ var xxx_messageInfo_VertexSpec proto.InternalMessageInfo func (m *VertexStatus) Reset() { *m = VertexStatus{} } func (*VertexStatus) ProtoMessage() {} func (*VertexStatus) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{69} + return fileDescriptor_9d0d1b17d3865563, []int{73} } func (m *VertexStatus) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2011,7 +2123,7 @@ var xxx_messageInfo_VertexStatus proto.InternalMessageInfo func (m *Watermark) Reset() { *m = Watermark{} } func (*Watermark) ProtoMessage() {} func (*Watermark) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{70} + return fileDescriptor_9d0d1b17d3865563, []int{74} } func (m *Watermark) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2039,7 +2151,7 @@ var xxx_messageInfo_Watermark proto.InternalMessageInfo func (m *Window) Reset() { *m = Window{} } func (*Window) ProtoMessage() {} func (*Window) Descriptor() ([]byte, []int) { - return fileDescriptor_9d0d1b17d3865563, []int{71} + return fileDescriptor_9d0d1b17d3865563, []int{75} } func (m *Window) XXX_Unmarshal(b []byte) error { return m.Unmarshal(b) @@ -2092,6 +2204,7 @@ func init() { proto.RegisterMapType((map[string]string)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.GetRedisServiceSpecReq.LabelsEntry") proto.RegisterType((*GetRedisStatefulSetSpecReq)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.GetRedisStatefulSetSpecReq") proto.RegisterMapType((map[string]string)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.GetRedisStatefulSetSpecReq.LabelsEntry") + proto.RegisterType((*GetSideInputDeploymentReq)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.GetSideInputDeploymentReq") proto.RegisterType((*GetVertexPodSpecReq)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.GetVertexPodSpecReq") proto.RegisterType((*GroupBy)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.GroupBy") proto.RegisterType((*HTTPSource)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.HTTPSource") @@ -2126,6 +2239,9 @@ func init() { proto.RegisterType((*SASL)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.SASL") proto.RegisterType((*SASLPlain)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.SASLPlain") proto.RegisterType((*Scale)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.Scale") + proto.RegisterType((*SideInput)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.SideInput") + proto.RegisterType((*SideInputTrigger)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.SideInputTrigger") + proto.RegisterType((*SideInputsManagerTemplate)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.SideInputsManagerTemplate") proto.RegisterType((*Sink)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.Sink") proto.RegisterType((*SlidingWindow)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.SlidingWindow") proto.RegisterType((*Source)(nil), "github.com.numaproj.numaflow.pkg.apis.numaflow.v1alpha1.Source") @@ -2153,401 +2269,417 @@ func init() { } var fileDescriptor_9d0d1b17d3865563 = []byte{ - // 6292 bytes of a gzipped FileDescriptorProto - 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xe4, 0x7d, 0x5d, 0x8c, 0x5c, 0xc9, - 0x55, 0xff, 0xf6, 0xe7, 0x74, 0x9f, 0x9e, 0x19, 0xdb, 0xe5, 0x5d, 0xef, 0x78, 0xe2, 0xf5, 0x38, - 0x37, 0xff, 0xdd, 0xbf, 0xf3, 0xff, 0x27, 0x63, 0xd6, 0x6c, 0xc8, 0x06, 0x48, 0x76, 0xa7, 0x67, - 0x3c, 0x5e, 0xaf, 0x67, 0xec, 0xc9, 0xe9, 0x19, 0x7b, 0x93, 0x85, 0x2c, 0x35, 0xb7, 0x6b, 0x7a, - 0xee, 0xf6, 0xed, 0x7b, 0x3b, 0xf7, 0x56, 0x8f, 0x3d, 0x0b, 0x11, 0x09, 0x79, 0xd8, 0x44, 0x44, - 0x04, 0x09, 0x21, 0x45, 0xa0, 0x20, 0x21, 0x21, 0xf1, 0x80, 0x22, 0x21, 0x41, 0x78, 0x00, 0x21, - 0xe0, 0x05, 0x05, 0x1e, 0x20, 0x0f, 0x48, 0x04, 0x81, 0x46, 0x64, 0x78, 0xe2, 0x01, 0x14, 0x11, - 0x09, 0x45, 0x16, 0x12, 0xa8, 0xbe, 0xee, 0x57, 0xdf, 0xb6, 0x3d, 0xdd, 0x33, 0x1b, 0x47, 0xbc, - 0xf5, 0xad, 0x73, 0xea, 0x77, 0xea, 0xd6, 0xad, 0x3a, 0x75, 0x3e, 0xaa, 0xaa, 0xe1, 0x7a, 0xc7, - 0xe1, 0xbb, 0x83, 0xed, 0x45, 0xdb, 0xef, 0x5d, 0xf1, 0x06, 0x3d, 0xda, 0x0f, 0xfc, 0xb7, 0xe5, - 0x8f, 0x1d, 0xd7, 0xbf, 0x77, 0xa5, 0xdf, 0xed, 0x5c, 0xa1, 0x7d, 0x27, 0x8c, 0x4b, 0xf6, 0x5e, - 0xa4, 0x6e, 0x7f, 0x97, 0xbe, 0x78, 0xa5, 0xc3, 0x3c, 0x16, 0x50, 0xce, 0xda, 0x8b, 0xfd, 0xc0, - 0xe7, 0x3e, 0xf9, 0x68, 0x0c, 0xb4, 0x68, 0x80, 0x16, 0x4d, 0xb5, 0xc5, 0x7e, 0xb7, 0xb3, 0x28, - 0x80, 0xe2, 0x12, 0x03, 0x34, 0xff, 0xe1, 0x44, 0x0b, 0x3a, 0x7e, 0xc7, 0xbf, 0x22, 0xf1, 0xb6, - 0x07, 0x3b, 0xf2, 0x49, 0x3e, 0xc8, 0x5f, 0x4a, 0xce, 0xbc, 0xd5, 0x7d, 0x39, 0x5c, 0x74, 0x7c, - 0xd1, 0xac, 0x2b, 0xb6, 0x1f, 0xb0, 0x2b, 0x7b, 0x43, 0x6d, 0x99, 0x7f, 0x29, 0xe6, 0xe9, 0x51, - 0x7b, 0xd7, 0xf1, 0x58, 0xb0, 0x6f, 0xde, 0xe5, 0x4a, 0xc0, 0x42, 0x7f, 0x10, 0xd8, 0xec, 0x48, - 0xb5, 0xc2, 0x2b, 0x3d, 0xc6, 0x69, 0x9e, 0xac, 0x2b, 0xa3, 0x6a, 0x05, 0x03, 0x8f, 0x3b, 0xbd, - 0x61, 0x31, 0x3f, 0xf1, 0xa8, 0x0a, 0xa1, 0xbd, 0xcb, 0x7a, 0x34, 0x5b, 0xcf, 0xfa, 0xc7, 0x3a, - 0x9c, 0x5d, 0xda, 0x0e, 0x79, 0x40, 0x6d, 0xbe, 0xe1, 0xb7, 0x37, 0x59, 0xaf, 0xef, 0x52, 0xce, - 0x48, 0x17, 0x6a, 0xa2, 0x6d, 0x6d, 0xca, 0xe9, 0x5c, 0xe1, 0x52, 0xe1, 0x72, 0xe3, 0xea, 0xd2, - 0xe2, 0x98, 0xdf, 0x62, 0x71, 0x5d, 0x03, 0x35, 0xa7, 0x0f, 0x0f, 0x16, 0x6a, 0xe6, 0x09, 0x23, - 0x01, 0xe4, 0x6b, 0x05, 0x98, 0xf6, 0xfc, 0x36, 0x6b, 0x31, 0x97, 0xd9, 0xdc, 0x0f, 0xe6, 0x8a, - 0x97, 0x4a, 0x97, 0x1b, 0x57, 0x3f, 0x33, 0xb6, 0xc4, 0x9c, 0x37, 0x5a, 0xbc, 0x95, 0x10, 0x70, - 0xcd, 0xe3, 0xc1, 0x7e, 0xf3, 0xe9, 0x6f, 0x1d, 0x2c, 0x3c, 0x75, 0x78, 0xb0, 0x30, 0x9d, 0x24, - 0x61, 0xaa, 0x25, 0x64, 0x0b, 0x1a, 0xdc, 0x77, 0x45, 0x97, 0x39, 0xbe, 0x17, 0xce, 0x95, 0x64, - 0xc3, 0x2e, 0x2e, 0xaa, 0xde, 0x16, 0xe2, 0x17, 0xc5, 0x70, 0x59, 0xdc, 0x7b, 0x71, 0x71, 0x33, - 0x62, 0x6b, 0x9e, 0xd5, 0xc0, 0x8d, 0xb8, 0x2c, 0xc4, 0x24, 0x0e, 0x61, 0x70, 0x2a, 0x64, 0xf6, - 0x20, 0x70, 0xf8, 0xfe, 0xb2, 0xef, 0x71, 0x76, 0x9f, 0xcf, 0x95, 0x65, 0x2f, 0xbf, 0x90, 0x07, - 0xbd, 0xe1, 0xb7, 0x5b, 0x69, 0xee, 0xe6, 0xd9, 0xc3, 0x83, 0x85, 0x53, 0x99, 0x42, 0xcc, 0x62, - 0x12, 0x0f, 0x4e, 0x3b, 0x3d, 0xda, 0x61, 0x1b, 0x03, 0xd7, 0x6d, 0x31, 0x3b, 0x60, 0x3c, 0x9c, - 0xab, 0xc8, 0x57, 0xb8, 0x9c, 0x27, 0x67, 0xcd, 0xb7, 0xa9, 0x7b, 0x7b, 0xfb, 0x6d, 0x66, 0x73, - 0x64, 0x3b, 0x2c, 0x60, 0x9e, 0xcd, 0x9a, 0x73, 0xfa, 0x65, 0x4e, 0xdf, 0xc8, 0x20, 0xe1, 0x10, - 0x36, 0xb9, 0x0e, 0x67, 0xfa, 0x81, 0xe3, 0xcb, 0x26, 0xb8, 0x34, 0x0c, 0x6f, 0xd1, 0x1e, 0x9b, - 0xab, 0x5e, 0x2a, 0x5c, 0xae, 0x37, 0xcf, 0x6b, 0x98, 0x33, 0x1b, 0x59, 0x06, 0x1c, 0xae, 0x43, - 0x2e, 0x43, 0xcd, 0x14, 0xce, 0x4d, 0x5d, 0x2a, 0x5c, 0xae, 0xa8, 0xb1, 0x63, 0xea, 0x62, 0x44, - 0x25, 0xab, 0x50, 0xa3, 0x3b, 0x3b, 0x8e, 0x27, 0x38, 0x6b, 0xb2, 0x0b, 0x2f, 0xe4, 0xbd, 0xda, - 0x92, 0xe6, 0x51, 0x38, 0xe6, 0x09, 0xa3, 0xba, 0xe4, 0x75, 0x20, 0x21, 0x0b, 0xf6, 0x1c, 0x9b, - 0x2d, 0xd9, 0xb6, 0x3f, 0xf0, 0xb8, 0x6c, 0x7b, 0x5d, 0xb6, 0x7d, 0x5e, 0xb7, 0x9d, 0xb4, 0x86, - 0x38, 0x30, 0xa7, 0x16, 0x79, 0x15, 0x4e, 0xeb, 0x69, 0x17, 0xf7, 0x02, 0x48, 0xa4, 0xa7, 0x45, - 0x47, 0x62, 0x86, 0x86, 0x43, 0xdc, 0xa4, 0x0d, 0x17, 0xe8, 0x80, 0xfb, 0x3d, 0x01, 0x99, 0x16, - 0xba, 0xe9, 0x77, 0x99, 0x37, 0xd7, 0xb8, 0x54, 0xb8, 0x5c, 0x6b, 0x5e, 0x3a, 0x3c, 0x58, 0xb8, - 0xb0, 0xf4, 0x10, 0x3e, 0x7c, 0x28, 0x0a, 0xb9, 0x0d, 0xf5, 0xb6, 0x17, 0x6e, 0xf8, 0xae, 0x63, - 0xef, 0xcf, 0x4d, 0xcb, 0x06, 0xbe, 0xa8, 0x5f, 0xb5, 0xbe, 0x72, 0xab, 0xa5, 0x08, 0x0f, 0x0e, - 0x16, 0x2e, 0x0c, 0x6b, 0xc7, 0xc5, 0x88, 0x8e, 0x31, 0x06, 0x59, 0x97, 0x80, 0xcb, 0xbe, 0xb7, - 0xe3, 0x74, 0xe6, 0x66, 0xe4, 0xd7, 0xb8, 0x34, 0x62, 0x40, 0xaf, 0xdc, 0x6a, 0x29, 0xbe, 0xe6, - 0x8c, 0x16, 0xa7, 0x1e, 0x31, 0x46, 0x98, 0x7f, 0x05, 0xce, 0x0c, 0xcd, 0x5a, 0x72, 0x1a, 0x4a, - 0x5d, 0xb6, 0x2f, 0x95, 0x52, 0x1d, 0xc5, 0x4f, 0xf2, 0x34, 0x54, 0xf6, 0xa8, 0x3b, 0x60, 0x73, - 0x45, 0x59, 0xa6, 0x1e, 0x7e, 0xb2, 0xf8, 0x72, 0xc1, 0xfa, 0x15, 0x80, 0x59, 0xa3, 0x0b, 0xee, - 0xb0, 0x80, 0xb3, 0xfb, 0xe4, 0x12, 0x94, 0x3d, 0xf1, 0x3d, 0x64, 0xfd, 0xe6, 0xb4, 0x7e, 0xdd, - 0xb2, 0xfc, 0x0e, 0x92, 0x42, 0x6c, 0xa8, 0x2a, 0x5d, 0x2e, 0xf1, 0x1a, 0x57, 0x5f, 0x19, 0x5b, - 0x0d, 0xb5, 0x24, 0x4c, 0x13, 0x0e, 0x0f, 0x16, 0xaa, 0xea, 0x37, 0x6a, 0x68, 0xf2, 0x26, 0x94, - 0x43, 0xc7, 0xeb, 0xce, 0x95, 0xa4, 0x88, 0x8f, 0x8f, 0x2f, 0xc2, 0xf1, 0xba, 0xcd, 0x9a, 0x78, - 0x03, 0xf1, 0x0b, 0x25, 0x28, 0xb9, 0x0b, 0xa5, 0x41, 0x7b, 0x47, 0x6b, 0x94, 0x9f, 0x1e, 0x1b, - 0x7b, 0x6b, 0x65, 0xb5, 0x39, 0x75, 0x78, 0xb0, 0x50, 0xda, 0x5a, 0x59, 0x45, 0x81, 0x48, 0xbe, - 0x5a, 0x80, 0x33, 0xb6, 0xef, 0x71, 0x2a, 0xd6, 0x17, 0xa3, 0x59, 0xe7, 0x2a, 0x52, 0xce, 0xeb, - 0x63, 0xcb, 0x59, 0xce, 0x22, 0x36, 0x9f, 0x11, 0x8a, 0x62, 0xa8, 0x18, 0x87, 0x65, 0x93, 0xdf, - 0x2c, 0xc0, 0x33, 0x62, 0x02, 0x0f, 0x31, 0x4b, 0xb5, 0x73, 0xbc, 0xad, 0x3a, 0x7f, 0x78, 0xb0, - 0xf0, 0xcc, 0x8d, 0x3c, 0x61, 0x98, 0xdf, 0x06, 0xd1, 0xba, 0xb3, 0x74, 0x78, 0x2d, 0x92, 0x2a, - 0xad, 0x71, 0x75, 0xed, 0x38, 0xd7, 0xb7, 0xe6, 0xfb, 0xf4, 0x50, 0xce, 0x5b, 0xce, 0x31, 0xaf, - 0x15, 0xe4, 0x1a, 0x4c, 0xed, 0xf9, 0xee, 0xa0, 0xc7, 0xc2, 0xb9, 0x9a, 0x5c, 0x14, 0xe6, 0xf3, - 0xe6, 0xea, 0x1d, 0xc9, 0xd2, 0x3c, 0xa5, 0xe1, 0xa7, 0xd4, 0x73, 0x88, 0xa6, 0x2e, 0x71, 0xa0, - 0xea, 0x3a, 0x3d, 0x87, 0x87, 0x52, 0x5b, 0x36, 0xae, 0x5e, 0x1b, 0xfb, 0xb5, 0xd4, 0x14, 0x5d, - 0x93, 0x60, 0x6a, 0xd6, 0xa8, 0xdf, 0xa8, 0x05, 0x10, 0x1b, 0x2a, 0xa1, 0x4d, 0x5d, 0xa5, 0x4d, - 0x1b, 0x57, 0x3f, 0x31, 0xfe, 0xb4, 0x11, 0x28, 0xcd, 0x19, 0xfd, 0x4e, 0x15, 0xf9, 0x88, 0x0a, - 0x9b, 0xfc, 0x2c, 0xcc, 0xa6, 0xbe, 0x66, 0x38, 0xd7, 0x90, 0xbd, 0xf3, 0x5c, 0x5e, 0xef, 0x44, - 0x5c, 0xcd, 0x73, 0x1a, 0x6c, 0x36, 0x35, 0x42, 0x42, 0xcc, 0x80, 0x91, 0x9b, 0x50, 0x0b, 0x9d, - 0x36, 0xb3, 0x69, 0x10, 0xce, 0x4d, 0x3f, 0x0e, 0xf0, 0x69, 0x0d, 0x5c, 0x6b, 0xe9, 0x6a, 0x18, - 0x01, 0x90, 0x45, 0x80, 0x3e, 0x0d, 0xb8, 0xa3, 0xac, 0x93, 0x19, 0xb9, 0x52, 0xce, 0x1e, 0x1e, - 0x2c, 0xc0, 0x46, 0x54, 0x8a, 0x09, 0x0e, 0xeb, 0x2e, 0xcc, 0x2c, 0x0d, 0xf8, 0xae, 0x1f, 0x38, - 0xef, 0x48, 0x4b, 0x84, 0xac, 0x42, 0x85, 0xcb, 0x15, 0x45, 0x19, 0x79, 0xcf, 0xe7, 0x35, 0x45, - 0xad, 0xee, 0x37, 0xd9, 0xbe, 0x51, 0xc4, 0xcd, 0xba, 0xe8, 0x34, 0xb5, 0xc2, 0xa8, 0xea, 0xd6, - 0x6f, 0x17, 0xa0, 0xde, 0xa4, 0xa1, 0x63, 0x0b, 0x78, 0xb2, 0x0c, 0xe5, 0x41, 0xc8, 0x82, 0xa3, - 0x81, 0x4a, 0x2d, 0xb6, 0x15, 0xb2, 0x00, 0x65, 0x65, 0x72, 0x1b, 0x6a, 0x7d, 0x1a, 0x86, 0xf7, - 0xfc, 0xa0, 0xad, 0x35, 0xf1, 0x63, 0x02, 0x29, 0x53, 0x41, 0x57, 0xc5, 0x08, 0xc4, 0x6a, 0x40, - 0xbd, 0xe9, 0x52, 0xbb, 0xbb, 0xeb, 0xbb, 0xcc, 0xfa, 0x7e, 0x01, 0xce, 0x36, 0x07, 0x3b, 0x3b, - 0x2c, 0xd0, 0x2b, 0xa3, 0x5a, 0x73, 0x08, 0x83, 0x4a, 0xc0, 0xda, 0x4e, 0xa8, 0xdb, 0xbe, 0x32, - 0xf6, 0x10, 0x43, 0x81, 0xa2, 0x97, 0x38, 0xd9, 0x5f, 0xb2, 0x00, 0x15, 0x3a, 0x19, 0x40, 0xfd, - 0x6d, 0xc6, 0x43, 0x1e, 0x30, 0xda, 0xd3, 0x6f, 0xf7, 0xda, 0xd8, 0xa2, 0x5e, 0x67, 0xbc, 0x25, - 0x91, 0x92, 0x2b, 0x6a, 0x54, 0x88, 0xb1, 0x24, 0xeb, 0x2f, 0x2a, 0x30, 0xbd, 0xec, 0xf7, 0xb6, - 0x1d, 0x8f, 0xb5, 0xaf, 0xb5, 0x3b, 0x8c, 0xbc, 0x05, 0x65, 0xd6, 0xee, 0x30, 0xfd, 0xb6, 0xe3, - 0xaf, 0x43, 0x02, 0x2c, 0x5e, 0x4d, 0xc5, 0x13, 0x4a, 0x60, 0xb2, 0x06, 0xb3, 0x3b, 0x81, 0xdf, - 0x53, 0x53, 0x7b, 0x73, 0xbf, 0xaf, 0x57, 0xe9, 0xe6, 0xff, 0x31, 0xd3, 0x65, 0x35, 0x45, 0x7d, - 0x70, 0xb0, 0x00, 0xf1, 0x13, 0x66, 0xea, 0x92, 0x37, 0x60, 0x2e, 0x2e, 0x89, 0xc6, 0xf8, 0xb2, - 0x30, 0x69, 0xe4, 0x52, 0x5a, 0x69, 0x5e, 0x38, 0x3c, 0x58, 0x98, 0x5b, 0x1d, 0xc1, 0x83, 0x23, - 0x6b, 0x93, 0x77, 0x0b, 0x70, 0x3a, 0x26, 0x2a, 0xbd, 0xa3, 0x57, 0xd0, 0x63, 0x52, 0x68, 0xd2, - 0xf6, 0x5b, 0xcd, 0x88, 0xc0, 0x21, 0xa1, 0x64, 0x15, 0xa6, 0xb9, 0x9f, 0xe8, 0xaf, 0x8a, 0xec, - 0x2f, 0xcb, 0x38, 0x2b, 0x9b, 0xfe, 0xc8, 0xde, 0x4a, 0xd5, 0x23, 0x08, 0xe7, 0xcc, 0x73, 0xa6, - 0xa7, 0xaa, 0xb2, 0xa7, 0xe6, 0x0f, 0x0f, 0x16, 0xce, 0x6d, 0xe6, 0x72, 0xe0, 0x88, 0x9a, 0xe4, - 0x0b, 0x05, 0x98, 0x35, 0x24, 0xdd, 0x47, 0x53, 0xc7, 0xd9, 0x47, 0x44, 0x8c, 0x88, 0xcd, 0x94, - 0x00, 0xcc, 0x08, 0xb4, 0x7e, 0x50, 0x86, 0x7a, 0xa4, 0x1d, 0xc9, 0x07, 0xa0, 0x22, 0xdd, 0x10, - 0x6d, 0xd0, 0x45, 0x2a, 0x5d, 0x7a, 0x2b, 0xa8, 0x68, 0xe4, 0x79, 0x98, 0xb2, 0xfd, 0x5e, 0x8f, - 0x7a, 0x6d, 0xe9, 0x5a, 0xd6, 0x9b, 0x0d, 0xb1, 0x92, 0x2d, 0xab, 0x22, 0x34, 0x34, 0x72, 0x01, - 0xca, 0x34, 0xe8, 0x28, 0x2f, 0xaf, 0xae, 0xf4, 0xd1, 0x52, 0xd0, 0x09, 0x51, 0x96, 0x92, 0x8f, - 0x41, 0x89, 0x79, 0x7b, 0x73, 0xe5, 0xd1, 0x4b, 0xe5, 0x35, 0x6f, 0xef, 0x0e, 0x0d, 0x9a, 0x0d, - 0xdd, 0x86, 0xd2, 0x35, 0x6f, 0x0f, 0x45, 0x1d, 0xb2, 0x06, 0x53, 0xcc, 0xdb, 0x13, 0xdf, 0x5e, - 0xbb, 0x5f, 0xef, 0x1f, 0x51, 0x5d, 0xb0, 0x68, 0xab, 0x31, 0x5a, 0x70, 0x75, 0x31, 0x1a, 0x08, - 0xf2, 0x29, 0x98, 0x56, 0x6b, 0xef, 0xba, 0xf8, 0x26, 0xe1, 0x5c, 0x55, 0x42, 0x2e, 0x8c, 0x5e, - 0xbc, 0x25, 0x5f, 0xec, 0xee, 0x26, 0x0a, 0x43, 0x4c, 0x41, 0x91, 0x4f, 0x41, 0xdd, 0x44, 0x32, - 0xcc, 0x97, 0xcd, 0xf5, 0x14, 0x51, 0x33, 0x21, 0xfb, 0xec, 0xc0, 0x09, 0x58, 0x8f, 0x79, 0x3c, - 0x6c, 0x9e, 0x31, 0xbe, 0x83, 0xa1, 0x86, 0x18, 0xa3, 0x91, 0xed, 0x61, 0x97, 0x57, 0xf9, 0x6b, - 0x1f, 0x18, 0xa1, 0xd5, 0xc7, 0xf0, 0x77, 0x3f, 0x03, 0xa7, 0x22, 0x9f, 0x54, 0xbb, 0x35, 0xca, - 0x83, 0x7b, 0x49, 0x54, 0xbf, 0x91, 0x26, 0x3d, 0x38, 0x58, 0x78, 0x2e, 0xc7, 0xb1, 0x89, 0x19, - 0x30, 0x0b, 0x66, 0xfd, 0x59, 0x09, 0x86, 0xcd, 0xd2, 0x74, 0xa7, 0x15, 0x8e, 0xbb, 0xd3, 0xb2, - 0x2f, 0xa4, 0xd4, 0xe7, 0xcb, 0xba, 0xda, 0xe4, 0x2f, 0x95, 0xf7, 0x61, 0x4a, 0xc7, 0xfd, 0x61, - 0x9e, 0x94, 0xb9, 0x63, 0x7d, 0xa9, 0x0c, 0xb3, 0x2b, 0x94, 0xf5, 0x7c, 0xef, 0x91, 0x46, 0x7a, - 0xe1, 0x89, 0x30, 0xd2, 0x2f, 0x43, 0x2d, 0x60, 0x7d, 0xd7, 0xb1, 0x69, 0x28, 0x3f, 0xbd, 0x8e, - 0x84, 0xa0, 0x2e, 0xc3, 0x88, 0x3a, 0xc2, 0x39, 0x2b, 0x3d, 0x91, 0xce, 0x59, 0xf9, 0x87, 0xef, - 0x9c, 0x59, 0x5f, 0x28, 0x82, 0x34, 0x54, 0xc8, 0x25, 0x28, 0x8b, 0x45, 0x38, 0x1b, 0x12, 0x90, - 0x03, 0x47, 0x52, 0xc8, 0x3c, 0x14, 0xb9, 0xaf, 0x67, 0x1e, 0x68, 0x7a, 0x71, 0xd3, 0xc7, 0x22, - 0xf7, 0xc9, 0x3b, 0x00, 0xb6, 0xef, 0xb5, 0x1d, 0x13, 0x20, 0x9c, 0xec, 0xc5, 0x56, 0xfd, 0xe0, - 0x1e, 0x0d, 0xda, 0xcb, 0x11, 0xa2, 0x32, 0xe7, 0xe3, 0x67, 0x4c, 0x48, 0x23, 0xaf, 0x40, 0xd5, - 0xf7, 0x56, 0x07, 0xae, 0x2b, 0x3b, 0xb4, 0xde, 0xfc, 0xbf, 0xc2, 0x67, 0xba, 0x2d, 0x4b, 0x1e, - 0x1c, 0x2c, 0x9c, 0x57, 0xf6, 0xad, 0x78, 0xba, 0x1b, 0x38, 0xdc, 0xf1, 0x3a, 0x2d, 0x1e, 0x50, - 0xce, 0x3a, 0xfb, 0xa8, 0xab, 0x59, 0x14, 0x1a, 0xab, 0xce, 0x7d, 0xd6, 0xbe, 0xeb, 0x78, 0x6d, - 0xff, 0x1e, 0x41, 0xa8, 0xba, 0xcc, 0xeb, 0xf0, 0x5d, 0x3d, 0xf8, 0x17, 0x13, 0x53, 0x2d, 0x0a, - 0x2b, 0xc7, 0xcd, 0xef, 0x31, 0x4e, 0xc5, 0xe4, 0x5b, 0x19, 0xe8, 0xc0, 0xa7, 0xf2, 0xd9, 0x24, - 0x02, 0x6a, 0x24, 0x6b, 0x1f, 0xce, 0x0c, 0xbd, 0x14, 0x69, 0x43, 0x99, 0xd3, 0x8e, 0xd1, 0x96, - 0xab, 0x63, 0x77, 0xd7, 0x26, 0xed, 0x24, 0xba, 0x4a, 0xae, 0xd8, 0x9b, 0x54, 0xac, 0xd8, 0x02, - 0xdd, 0xfa, 0xaf, 0x02, 0xd4, 0x56, 0x07, 0x9e, 0x2d, 0x3d, 0x9d, 0x47, 0x07, 0x7e, 0xcc, 0xf2, - 0x5f, 0xcc, 0x5d, 0xfe, 0x07, 0x50, 0xed, 0xde, 0x8b, 0xcc, 0x83, 0xc6, 0xd5, 0xf5, 0xf1, 0xbf, - 0xb1, 0x6e, 0xd2, 0xe2, 0x4d, 0x89, 0xa7, 0x82, 0xd1, 0xb3, 0xba, 0x41, 0xd5, 0x9b, 0x77, 0xa5, - 0x50, 0x2d, 0x6c, 0xfe, 0x63, 0xd0, 0x48, 0xb0, 0x1d, 0x29, 0xfa, 0xf5, 0x47, 0x65, 0xa8, 0x5e, - 0x6f, 0xb5, 0x96, 0x36, 0x6e, 0x90, 0x8f, 0x40, 0x43, 0xc7, 0x29, 0x6f, 0xc5, 0x7d, 0x10, 0x85, - 0xa9, 0x5b, 0x31, 0x09, 0x93, 0x7c, 0xc2, 0xb8, 0x0a, 0x18, 0x75, 0x7b, 0x7a, 0xe8, 0x47, 0xc6, - 0x15, 0x8a, 0x42, 0x54, 0x34, 0x42, 0x61, 0x56, 0xf8, 0x6b, 0xa2, 0x0b, 0x95, 0x2f, 0xa6, 0x27, - 0xc1, 0x63, 0x7a, 0x6b, 0xd2, 0xe4, 0xdb, 0x4a, 0x01, 0x60, 0x06, 0x90, 0xbc, 0x0c, 0x35, 0x3a, - 0xe0, 0xbb, 0xd2, 0x1c, 0x56, 0x23, 0xfd, 0x82, 0x0c, 0xe3, 0xea, 0xb2, 0x07, 0x07, 0x0b, 0xd3, - 0x37, 0xb1, 0xf9, 0x11, 0xf3, 0x8c, 0x11, 0xb7, 0x68, 0x9c, 0xf1, 0xff, 0x74, 0xe3, 0x2a, 0x47, - 0x6e, 0xdc, 0x46, 0x0a, 0x00, 0x33, 0x80, 0xe4, 0x4d, 0x98, 0xee, 0xb2, 0x7d, 0x4e, 0xb7, 0xb5, - 0x80, 0xea, 0x51, 0x04, 0x9c, 0x16, 0x06, 0xd9, 0xcd, 0x44, 0x75, 0x4c, 0x81, 0x91, 0x10, 0x9e, - 0xee, 0xb2, 0x60, 0x9b, 0x05, 0xbe, 0xf6, 0x25, 0xb5, 0x90, 0xa9, 0xa3, 0x08, 0x99, 0x3b, 0x3c, - 0x58, 0x78, 0xfa, 0x66, 0x0e, 0x0c, 0xe6, 0x82, 0x5b, 0x3f, 0x28, 0xc0, 0xa9, 0xeb, 0x2a, 0x51, - 0xe4, 0x07, 0x6a, 0x49, 0x25, 0xe7, 0xa1, 0x14, 0xf4, 0x07, 0x72, 0xe4, 0x94, 0x54, 0x54, 0x10, - 0x37, 0xb6, 0x50, 0x94, 0x91, 0x37, 0xa0, 0xd6, 0xd6, 0x1a, 0x40, 0xbb, 0xb2, 0x47, 0xd5, 0x1b, - 0x72, 0x49, 0x33, 0x4f, 0x18, 0xa1, 0x09, 0xbb, 0xbd, 0x17, 0x76, 0x5a, 0xce, 0x3b, 0x4c, 0x7b, - 0x77, 0xd2, 0x6e, 0x5f, 0x57, 0x45, 0x68, 0x68, 0x62, 0x8d, 0xec, 0xb2, 0x7d, 0xe5, 0xdb, 0x94, - 0xe3, 0x35, 0xf2, 0xa6, 0x2e, 0xc3, 0x88, 0x4a, 0x16, 0xcc, 0x64, 0x11, 0xa3, 0xa0, 0xac, 0xfc, - 0xf2, 0x3b, 0xa2, 0x40, 0xcf, 0x1b, 0xeb, 0xab, 0x45, 0x38, 0x77, 0x9d, 0x71, 0x65, 0x22, 0xac, - 0xb0, 0xbe, 0xeb, 0xef, 0x0b, 0x3b, 0x0d, 0xd9, 0x67, 0xc9, 0xab, 0x00, 0x4e, 0xb8, 0xdd, 0xda, - 0xb3, 0xe5, 0x30, 0x54, 0x53, 0xe8, 0x92, 0x9e, 0x11, 0x70, 0xa3, 0xd5, 0xd4, 0x94, 0x07, 0xa9, - 0x27, 0x4c, 0xd4, 0x89, 0x7d, 0x95, 0xe2, 0x43, 0x7c, 0x95, 0x16, 0x40, 0x3f, 0xb6, 0xf6, 0x4a, - 0x92, 0xf3, 0xc7, 0x8d, 0x98, 0xa3, 0x18, 0x7a, 0x09, 0x98, 0x09, 0xec, 0x2f, 0xeb, 0x8f, 0x4b, - 0x30, 0x7f, 0x9d, 0xf1, 0x28, 0x9c, 0xa0, 0x95, 0x45, 0xab, 0xcf, 0x6c, 0xd1, 0x2b, 0xef, 0x16, - 0xa0, 0xea, 0xd2, 0x6d, 0xe6, 0x0a, 0x65, 0x2e, 0xd0, 0xdf, 0x1a, 0x5b, 0x2f, 0x8e, 0x96, 0xb2, - 0xb8, 0x26, 0x25, 0x64, 0x34, 0xa5, 0x2a, 0x44, 0x2d, 0x5e, 0xe8, 0x38, 0xdb, 0x1d, 0x84, 0x9c, - 0x05, 0x1b, 0x7e, 0xc0, 0xb5, 0xb1, 0x14, 0xe9, 0xb8, 0xe5, 0x98, 0x84, 0x49, 0x3e, 0x72, 0x15, - 0xc0, 0x76, 0x1d, 0xe6, 0x71, 0x59, 0x4b, 0x0d, 0x33, 0x62, 0xfa, 0x7b, 0x39, 0xa2, 0x60, 0x82, - 0x4b, 0x88, 0xea, 0xf9, 0x9e, 0xc3, 0x7d, 0x25, 0xaa, 0x9c, 0x16, 0xb5, 0x1e, 0x93, 0x30, 0xc9, - 0x27, 0xab, 0x31, 0x1e, 0x38, 0x76, 0x28, 0xab, 0x55, 0x32, 0xd5, 0x62, 0x12, 0x26, 0xf9, 0xc4, - 0x12, 0x90, 0x78, 0xff, 0x23, 0x2d, 0x01, 0x7f, 0x52, 0x83, 0x8b, 0xa9, 0x6e, 0xe5, 0x94, 0xb3, - 0x9d, 0x81, 0xdb, 0x62, 0xdc, 0x7c, 0xc0, 0x31, 0x97, 0x86, 0x5f, 0x8e, 0xbf, 0xbb, 0xca, 0xd6, - 0xda, 0xc7, 0xf3, 0xdd, 0x87, 0x1a, 0xf8, 0x58, 0xdf, 0xfe, 0x0a, 0xd4, 0x3d, 0xca, 0x43, 0x39, - 0x91, 0xf4, 0x9c, 0x89, 0x1c, 0xab, 0x5b, 0x86, 0x80, 0x31, 0x0f, 0xd9, 0x80, 0xa7, 0x75, 0x17, - 0x5f, 0xbb, 0xdf, 0xf7, 0x03, 0xce, 0x02, 0x55, 0x57, 0xaf, 0x2e, 0xba, 0xee, 0xd3, 0xeb, 0x39, - 0x3c, 0x98, 0x5b, 0x93, 0xac, 0xc3, 0x59, 0x5b, 0x65, 0xb0, 0x98, 0xeb, 0xd3, 0xb6, 0x01, 0x54, - 0xd1, 0x9b, 0xc8, 0xee, 0x5f, 0x1e, 0x66, 0xc1, 0xbc, 0x7a, 0xd9, 0xd1, 0x5c, 0x1d, 0x6b, 0x34, - 0x4f, 0x8d, 0x33, 0x9a, 0x6b, 0xe3, 0x8d, 0xe6, 0xfa, 0xe3, 0x8d, 0x66, 0xd1, 0xf3, 0x62, 0x1c, - 0xb1, 0x40, 0xac, 0xd6, 0x6a, 0xc1, 0x49, 0x24, 0x48, 0xa3, 0x9e, 0x6f, 0xe5, 0xf0, 0x60, 0x6e, - 0x4d, 0xb2, 0x0d, 0xf3, 0xaa, 0xfc, 0x9a, 0x67, 0x07, 0xfb, 0x7d, 0xb1, 0x72, 0x24, 0x70, 0x1b, - 0xa9, 0xf0, 0xd9, 0x7c, 0x6b, 0x24, 0x27, 0x3e, 0x04, 0x85, 0xfc, 0x14, 0xcc, 0xa8, 0xaf, 0xb4, - 0x4e, 0xfb, 0x12, 0x56, 0xa5, 0x4b, 0x9f, 0xd1, 0xb0, 0x33, 0xcb, 0x49, 0x22, 0xa6, 0x79, 0xc9, - 0x12, 0x9c, 0xea, 0xef, 0xd9, 0xe2, 0xe7, 0x8d, 0x9d, 0x5b, 0x8c, 0xb5, 0x59, 0x5b, 0x86, 0xea, - 0xeb, 0xcd, 0x67, 0x8d, 0x17, 0xbf, 0x91, 0x26, 0x63, 0x96, 0x9f, 0xbc, 0x0c, 0xd3, 0x21, 0xa7, - 0x01, 0xd7, 0x31, 0xab, 0xb9, 0x59, 0x95, 0x4e, 0x36, 0x21, 0x9d, 0x56, 0x82, 0x86, 0x29, 0xce, - 0x49, 0xb4, 0xc7, 0x03, 0xb5, 0x18, 0xca, 0xc0, 0x75, 0x46, 0xed, 0x7f, 0x31, 0xab, 0xf6, 0xdf, - 0x9c, 0x64, 0xfa, 0xe7, 0x48, 0x78, 0xac, 0x69, 0xff, 0x3a, 0x90, 0x40, 0x87, 0xd9, 0x95, 0x73, - 0x97, 0xd0, 0xfc, 0x51, 0xd2, 0x1e, 0x87, 0x38, 0x30, 0xa7, 0x16, 0x69, 0xc1, 0x33, 0x21, 0xf3, - 0xb8, 0xe3, 0x31, 0x37, 0x0d, 0xa7, 0x96, 0x84, 0xe7, 0x34, 0xdc, 0x33, 0xad, 0x3c, 0x26, 0xcc, - 0xaf, 0x3b, 0x49, 0xe7, 0xff, 0x53, 0x5d, 0xae, 0xbb, 0xaa, 0x6b, 0x8e, 0x4d, 0x6d, 0xbf, 0x9b, - 0x55, 0xdb, 0x6f, 0x4d, 0xfe, 0xdd, 0xc6, 0x53, 0xd9, 0x57, 0x01, 0xe4, 0x57, 0x48, 0xea, 0xec, - 0x48, 0x53, 0x61, 0x44, 0xc1, 0x04, 0x97, 0x98, 0x85, 0xa6, 0x9f, 0x93, 0xea, 0x3a, 0x9a, 0x85, - 0xad, 0x24, 0x11, 0xd3, 0xbc, 0x23, 0x55, 0x7e, 0x65, 0x6c, 0x95, 0xff, 0x3a, 0x90, 0x54, 0x68, - 0x41, 0xe1, 0x55, 0xd3, 0x7b, 0x46, 0x6e, 0x0c, 0x71, 0x60, 0x4e, 0xad, 0x11, 0x43, 0x79, 0xea, - 0x78, 0x87, 0x72, 0x6d, 0xfc, 0xa1, 0x4c, 0xde, 0x82, 0xf3, 0x52, 0x94, 0xee, 0x9f, 0x34, 0xb0, - 0x52, 0xfe, 0xef, 0xd7, 0xc0, 0xe7, 0x71, 0x14, 0x23, 0x8e, 0xc6, 0x10, 0xdf, 0xc7, 0x0e, 0x58, - 0x5b, 0x08, 0xa7, 0xee, 0xe8, 0x85, 0x61, 0x39, 0x87, 0x07, 0x73, 0x6b, 0x8a, 0x21, 0xc6, 0xc5, - 0x30, 0xa4, 0xdb, 0x2e, 0x6b, 0xeb, 0x3d, 0x33, 0xd1, 0x10, 0xdb, 0x5c, 0x6b, 0x69, 0x0a, 0x26, - 0xb8, 0xf2, 0x74, 0xf5, 0xf4, 0x11, 0x75, 0xf5, 0x75, 0x19, 0x87, 0xdb, 0x49, 0x2d, 0x09, 0x5a, - 0xe1, 0x47, 0xbb, 0xa0, 0x96, 0xb3, 0x0c, 0x38, 0x5c, 0x47, 0x2e, 0x95, 0x76, 0xe0, 0xf4, 0x79, - 0x98, 0xc6, 0x9a, 0xcd, 0x2c, 0x95, 0x39, 0x3c, 0x98, 0x5b, 0x53, 0x18, 0x29, 0xbb, 0x8c, 0xba, - 0x7c, 0x37, 0x0d, 0x78, 0x2a, 0x6d, 0xa4, 0xbc, 0x36, 0xcc, 0x82, 0x79, 0xf5, 0x26, 0x51, 0x6f, - 0x5f, 0x29, 0xc2, 0xd9, 0xeb, 0x4c, 0xef, 0xca, 0xd9, 0xf0, 0xdb, 0x46, 0xaf, 0xfd, 0x2f, 0xf5, - 0xb2, 0xfe, 0xa3, 0x08, 0x53, 0xd7, 0x03, 0x7f, 0xd0, 0x6f, 0xee, 0x93, 0x0e, 0x54, 0xef, 0xc9, - 0x78, 0x9c, 0x0e, 0x8f, 0x8d, 0xbf, 0x01, 0x49, 0x85, 0xf5, 0x62, 0x15, 0xac, 0x9e, 0x51, 0xc3, - 0x8b, 0x9e, 0xea, 0xb2, 0x7d, 0xa6, 0xd2, 0xeb, 0xb5, 0xb8, 0xa7, 0x6e, 0x8a, 0x42, 0x54, 0x34, - 0xd2, 0x83, 0x53, 0xd4, 0x75, 0xfd, 0x7b, 0xac, 0xbd, 0x46, 0x39, 0xf3, 0x58, 0x68, 0x82, 0x9c, - 0x47, 0x75, 0xf2, 0x65, 0xa6, 0x60, 0x29, 0x0d, 0x85, 0x59, 0x6c, 0xf2, 0x36, 0x4c, 0x85, 0xdc, - 0x0f, 0x8c, 0x72, 0x6f, 0x5c, 0x5d, 0x1e, 0xfb, 0xed, 0x37, 0x9a, 0x9f, 0x6c, 0x29, 0x28, 0x15, - 0x37, 0xd0, 0x0f, 0x68, 0x04, 0x58, 0x5f, 0x2f, 0x00, 0xbc, 0xb6, 0xb9, 0xb9, 0xa1, 0x43, 0x1c, - 0x6d, 0x28, 0xd3, 0x41, 0x14, 0xfb, 0x1c, 0x3f, 0x28, 0x99, 0xda, 0x61, 0xa1, 0xe3, 0x88, 0x03, - 0xbe, 0x8b, 0x12, 0x9d, 0x7c, 0x10, 0xa6, 0xf4, 0x82, 0xac, 0xbb, 0x3d, 0x4a, 0x56, 0xe8, 0x45, - 0x1b, 0x0d, 0xdd, 0xfa, 0x5e, 0x11, 0xce, 0xdd, 0xf0, 0x38, 0x0b, 0x5a, 0x9c, 0xf5, 0x53, 0x9b, - 0x15, 0xc8, 0xcf, 0x0d, 0xed, 0xcf, 0xfd, 0xb1, 0xc7, 0xfb, 0x1c, 0x6a, 0x7b, 0xe7, 0x3a, 0xe3, - 0x34, 0x56, 0x85, 0x71, 0x59, 0x62, 0x53, 0xee, 0x00, 0xca, 0x61, 0x9f, 0xd9, 0x3a, 0xa2, 0xd3, - 0x1a, 0xbb, 0x37, 0xf2, 0x5f, 0x40, 0x4c, 0xf7, 0x38, 0x08, 0x2b, 0x27, 0xbf, 0x14, 0x47, 0x3e, - 0x07, 0xd5, 0x90, 0x53, 0x3e, 0x30, 0xa3, 0x6c, 0xeb, 0xb8, 0x05, 0x4b, 0xf0, 0x78, 0x4a, 0xa8, - 0x67, 0xd4, 0x42, 0xad, 0xef, 0x15, 0x60, 0x3e, 0xbf, 0xe2, 0x9a, 0x13, 0x72, 0xf2, 0x33, 0x43, - 0xdd, 0xfe, 0x98, 0xb3, 0x40, 0xd4, 0x96, 0x9d, 0x1e, 0xed, 0xe6, 0x31, 0x25, 0x89, 0x2e, 0xe7, - 0x50, 0x71, 0x38, 0xeb, 0x19, 0xd3, 0xec, 0xf6, 0x31, 0xbf, 0x7a, 0x42, 0x15, 0x0a, 0x29, 0xa8, - 0x84, 0x59, 0x5f, 0x2a, 0x8e, 0x7a, 0x65, 0xf1, 0x59, 0x88, 0x9b, 0xde, 0x10, 0x73, 0x73, 0xb2, - 0x0d, 0x31, 0xe9, 0x06, 0x0d, 0xef, 0x8b, 0xf9, 0x85, 0xe1, 0x7d, 0x31, 0xb7, 0x27, 0xdf, 0x17, - 0x93, 0xe9, 0x86, 0x91, 0xdb, 0x63, 0xbe, 0x52, 0x82, 0x0b, 0x0f, 0x1b, 0x36, 0x42, 0x35, 0xeb, - 0xd1, 0x39, 0xa9, 0x6a, 0x7e, 0xf8, 0x38, 0x24, 0x57, 0xa1, 0xd2, 0xdf, 0xa5, 0xa1, 0x59, 0xc4, - 0xcc, 0x5a, 0x5f, 0xd9, 0x10, 0x85, 0x0f, 0x0e, 0x16, 0x1a, 0x6a, 0xf1, 0x93, 0x8f, 0xa8, 0x58, - 0x85, 0x66, 0xe9, 0xb1, 0x30, 0x8c, 0xcd, 0xe9, 0x48, 0xb3, 0xac, 0xab, 0x62, 0x34, 0x74, 0xc2, - 0xa1, 0xaa, 0x5c, 0x54, 0xad, 0x64, 0xc7, 0xcf, 0x72, 0xe6, 0xec, 0xa1, 0x8a, 0x5f, 0x4a, 0x47, - 0x3b, 0xb4, 0x2c, 0xb2, 0x08, 0x65, 0x1e, 0xef, 0x68, 0x31, 0x56, 0x6d, 0x39, 0x67, 0x3d, 0x97, - 0x7c, 0xd6, 0xdf, 0xd6, 0xe0, 0x5c, 0xfe, 0x37, 0x14, 0xef, 0xba, 0xc7, 0x82, 0xd0, 0xf1, 0x3d, - 0x6d, 0x23, 0xc4, 0xfb, 0x13, 0x55, 0x31, 0x1a, 0xfa, 0x8f, 0x74, 0x06, 0xf5, 0x77, 0x0b, 0xc2, - 0xea, 0x56, 0x71, 0xa1, 0xf7, 0x22, 0x8b, 0xfa, 0x9c, 0xb2, 0xde, 0x47, 0x08, 0xc4, 0xd1, 0x6d, - 0x21, 0xbf, 0x53, 0x80, 0xb9, 0x5e, 0xc6, 0xac, 0x3f, 0xc1, 0x1d, 0xc2, 0x72, 0x9b, 0xd7, 0xfa, - 0x08, 0x79, 0x38, 0xb2, 0x25, 0xe4, 0x17, 0xa1, 0xd1, 0x17, 0xe3, 0x22, 0xe4, 0xcc, 0xb3, 0xcd, - 0x26, 0xe1, 0xf1, 0x47, 0xff, 0x46, 0x8c, 0x65, 0x72, 0xab, 0xcd, 0x53, 0xc2, 0x01, 0x4f, 0x10, - 0x30, 0x29, 0xf1, 0x09, 0xdf, 0x12, 0x7c, 0x19, 0x6a, 0x21, 0xe3, 0xdc, 0xf1, 0x3a, 0xa1, 0x74, - 0x16, 0xeb, 0x6a, 0xae, 0xb4, 0x74, 0x19, 0x46, 0x54, 0xf2, 0xff, 0xa1, 0x2e, 0xc3, 0x4c, 0x4b, - 0x41, 0x27, 0x9c, 0xab, 0xcb, 0x8c, 0xa9, 0xd4, 0xab, 0x2d, 0x53, 0x88, 0x31, 0x9d, 0xbc, 0x04, - 0xd3, 0xdb, 0x72, 0xfa, 0xea, 0xa3, 0x01, 0xca, 0xa5, 0x93, 0xb9, 0xaf, 0x66, 0xa2, 0x1c, 0x53, - 0x5c, 0xc2, 0x7d, 0x63, 0x51, 0x2c, 0x2e, 0xeb, 0xbe, 0xc5, 0x51, 0x3a, 0x4c, 0x70, 0x91, 0xe7, - 0xa0, 0xc4, 0xdd, 0x50, 0xba, 0x6c, 0xb5, 0xd8, 0xcc, 0xde, 0x5c, 0x6b, 0xa1, 0x28, 0xb7, 0xfe, - 0xbb, 0x00, 0xa7, 0x32, 0xbb, 0x25, 0x45, 0x95, 0x41, 0xe0, 0x6a, 0x35, 0x12, 0x55, 0xd9, 0xc2, - 0x35, 0x14, 0xe5, 0xe4, 0x2d, 0x6d, 0x15, 0x16, 0x27, 0x3c, 0x05, 0x75, 0x8b, 0xf2, 0x50, 0x98, - 0x81, 0x43, 0x06, 0xa1, 0x0c, 0xed, 0xc5, 0xed, 0xd1, 0xba, 0x3b, 0x11, 0xda, 0x8b, 0x69, 0x98, - 0xe2, 0xcc, 0xf8, 0xb7, 0xe5, 0xc7, 0xf1, 0x6f, 0xad, 0xbf, 0x2e, 0x41, 0xe3, 0x75, 0x7f, 0xfb, - 0x47, 0x64, 0xf7, 0x4b, 0xbe, 0x46, 0x2e, 0xfe, 0x10, 0x35, 0xf2, 0x16, 0x3c, 0xcb, 0xb9, 0xdb, - 0x62, 0xb6, 0xef, 0xb5, 0xc3, 0xa5, 0x1d, 0xce, 0x82, 0x55, 0xc7, 0x73, 0xc2, 0x5d, 0xd6, 0xd6, - 0x81, 0xc2, 0xf7, 0x1d, 0x1e, 0x2c, 0x3c, 0xbb, 0xb9, 0xb9, 0x96, 0xc7, 0x82, 0xa3, 0xea, 0xca, - 0x19, 0x42, 0xed, 0xae, 0xbf, 0xb3, 0x23, 0x77, 0x39, 0xea, 0x94, 0x92, 0x9a, 0x21, 0x89, 0x72, - 0x4c, 0x71, 0x59, 0xdf, 0x2c, 0x42, 0xfd, 0x26, 0xdd, 0xe9, 0xd2, 0x96, 0xe3, 0x75, 0xc9, 0xf3, - 0x30, 0xb5, 0x1d, 0xf8, 0x5d, 0x16, 0xa8, 0x98, 0xac, 0xde, 0xe5, 0xd8, 0x54, 0x45, 0x68, 0x68, - 0xc2, 0xeb, 0xe3, 0x7e, 0xdf, 0xb1, 0xb3, 0xfe, 0xf1, 0xa6, 0x28, 0x44, 0x45, 0x23, 0x77, 0xd5, - 0x3c, 0x2a, 0x4d, 0x78, 0x84, 0x64, 0x73, 0xad, 0xa5, 0x92, 0xc5, 0x66, 0x06, 0x92, 0x17, 0x52, - 0x96, 0x47, 0x7d, 0xa4, 0xad, 0xf0, 0x26, 0x94, 0x43, 0x1a, 0xba, 0x7a, 0xe9, 0x98, 0xe0, 0x80, - 0xcc, 0x52, 0x6b, 0x4d, 0x1f, 0x90, 0x59, 0x6a, 0xad, 0xa1, 0x04, 0xb5, 0x7e, 0x50, 0x84, 0x86, - 0xea, 0x37, 0xe5, 0xf9, 0x1d, 0x67, 0xcf, 0xbd, 0x22, 0x33, 0x05, 0xe1, 0xa0, 0xc7, 0x02, 0xe9, - 0xd0, 0xeb, 0xf9, 0x9c, 0x8c, 0xfc, 0xc4, 0xc4, 0x28, 0x5b, 0x10, 0x17, 0x99, 0xae, 0x2f, 0x9f, - 0x60, 0xd7, 0x57, 0x1e, 0xab, 0xeb, 0xab, 0x27, 0xd1, 0xf5, 0xbf, 0x5f, 0x80, 0xfa, 0x9a, 0xb3, - 0xc3, 0xec, 0x7d, 0xdb, 0x95, 0xfb, 0xb9, 0xdb, 0xcc, 0x65, 0x9c, 0x5d, 0x0f, 0xa8, 0xcd, 0x36, - 0x58, 0xe0, 0xc8, 0xa3, 0x8e, 0x62, 0x7e, 0x48, 0x0d, 0xa4, 0xf7, 0x73, 0xaf, 0x8c, 0xe0, 0xc1, - 0x91, 0xb5, 0xc9, 0x0d, 0x98, 0x6e, 0xb3, 0xd0, 0x09, 0x58, 0x7b, 0x23, 0x61, 0x47, 0x3f, 0x6f, - 0xb4, 0xea, 0x4a, 0x82, 0xf6, 0xe0, 0x60, 0x61, 0x66, 0xc3, 0xe9, 0x33, 0xd7, 0xf1, 0x98, 0x32, - 0xa8, 0x53, 0x55, 0xad, 0x0a, 0x94, 0xd6, 0xfc, 0x8e, 0xf5, 0xa5, 0x12, 0x44, 0x87, 0x57, 0xc9, - 0x97, 0x0b, 0xd0, 0xa0, 0x9e, 0xe7, 0x73, 0x7d, 0x30, 0x54, 0x25, 0x41, 0x70, 0xe2, 0x33, 0xb2, - 0x8b, 0x4b, 0x31, 0xa8, 0x8a, 0x9f, 0x47, 0x31, 0xfd, 0x04, 0x05, 0x93, 0xb2, 0xc9, 0x20, 0x13, - 0xd2, 0x5f, 0x9f, 0xbc, 0x15, 0x8f, 0x11, 0xc0, 0x9f, 0xff, 0x04, 0x9c, 0xce, 0x36, 0xf6, 0x28, - 0x11, 0xc0, 0x49, 0x82, 0x87, 0x5f, 0xac, 0x43, 0xe3, 0x16, 0xe5, 0xce, 0x1e, 0x93, 0xce, 0xe3, - 0xc9, 0x78, 0x03, 0xbf, 0x55, 0x80, 0x73, 0xe9, 0xe0, 0xfa, 0x09, 0xba, 0x04, 0x72, 0x33, 0x3e, - 0xe6, 0x4a, 0xc3, 0x11, 0xad, 0x90, 0xce, 0xc1, 0x50, 0xac, 0xfe, 0xa4, 0x9d, 0x83, 0xd6, 0x28, - 0x81, 0x38, 0xba, 0x2d, 0x3f, 0x2a, 0xce, 0xc1, 0x93, 0x7d, 0x98, 0x30, 0xe3, 0xba, 0x4c, 0x3d, - 0x31, 0xae, 0x4b, 0xed, 0x89, 0x30, 0x15, 0xfb, 0x09, 0xd7, 0xa5, 0x3e, 0x61, 0x04, 0x57, 0xe7, - 0xa3, 0x15, 0xda, 0x28, 0x17, 0x48, 0x6e, 0x2f, 0x35, 0x56, 0x3d, 0xb1, 0xa1, 0xb2, 0x4d, 0x43, - 0xc7, 0xd6, 0x86, 0x73, 0x73, 0xfc, 0x80, 0x8a, 0x39, 0x45, 0xa7, 0xa2, 0x63, 0xf2, 0x11, 0x15, - 0x76, 0x7c, 0x5a, 0xaf, 0x38, 0xd1, 0x69, 0x3d, 0xb2, 0x0c, 0x65, 0x4f, 0x28, 0xdb, 0xd2, 0x91, - 0xcf, 0xe7, 0xdd, 0xba, 0xc9, 0xf6, 0x51, 0x56, 0x16, 0xc6, 0x27, 0x88, 0xd7, 0xd7, 0x36, 0xd4, - 0x23, 0xdc, 0xa8, 0x0f, 0xc2, 0x54, 0x38, 0x90, 0x71, 0x66, 0xbd, 0x14, 0xc7, 0x61, 0x6f, 0x55, - 0x8c, 0x86, 0x2e, 0xcc, 0xac, 0xcf, 0x0e, 0xd8, 0xc0, 0x44, 0xb1, 0x22, 0x33, 0xeb, 0x93, 0xa2, - 0x10, 0x15, 0xed, 0xe4, 0xac, 0x24, 0xe3, 0xef, 0x55, 0x4e, 0xc8, 0xdf, 0xb3, 0x3e, 0x5f, 0x04, - 0x88, 0x53, 0x13, 0xe4, 0xeb, 0x05, 0x78, 0x26, 0x9a, 0x65, 0x5c, 0x9d, 0xcd, 0x59, 0x76, 0xa9, - 0xd3, 0x9b, 0xd8, 0x05, 0xcb, 0x9b, 0xe1, 0x52, 0xed, 0x6c, 0xe4, 0x89, 0xc3, 0xfc, 0x56, 0x10, - 0x84, 0x1a, 0xeb, 0xf5, 0xf9, 0xfe, 0x8a, 0x13, 0xe8, 0x61, 0x97, 0x7b, 0xb8, 0xe5, 0x9a, 0xe6, - 0x51, 0x55, 0xf5, 0x39, 0x0c, 0x39, 0x73, 0x0c, 0x05, 0x23, 0x1c, 0xeb, 0x6b, 0x45, 0x38, 0x9b, - 0xd3, 0x3a, 0xf2, 0x2a, 0x9c, 0xd6, 0xb9, 0x99, 0xf8, 0xe2, 0x84, 0x42, 0x7c, 0x71, 0x42, 0x2b, - 0x43, 0xc3, 0x21, 0x6e, 0xf2, 0x16, 0x00, 0xb5, 0x6d, 0x16, 0x86, 0xeb, 0x7e, 0xdb, 0x18, 0x7d, - 0xaf, 0x08, 0x77, 0x78, 0x29, 0x2a, 0x7d, 0x70, 0xb0, 0xf0, 0xe1, 0xbc, 0x9c, 0x5e, 0xe6, 0xed, - 0xe3, 0x0a, 0x98, 0x80, 0x24, 0x9f, 0x01, 0x50, 0x27, 0xa6, 0xa2, 0x5d, 0xa9, 0x8f, 0xc8, 0x01, - 0x2c, 0x9a, 0xd3, 0x3c, 0x8b, 0x9f, 0x1c, 0x50, 0x8f, 0x3b, 0x7c, 0x5f, 0x6d, 0xe9, 0xbf, 0x13, - 0xa1, 0x60, 0x02, 0xd1, 0xfa, 0xcb, 0x22, 0xd4, 0x8c, 0x31, 0xfa, 0x1e, 0x64, 0x79, 0x3a, 0xa9, - 0x2c, 0xcf, 0xf8, 0xa7, 0xf8, 0x4c, 0x93, 0x47, 0xe6, 0x75, 0xfc, 0x4c, 0x5e, 0xe7, 0xfa, 0xe4, - 0xa2, 0x1e, 0x9e, 0xc9, 0xf9, 0x46, 0x11, 0x66, 0x0d, 0xab, 0x3e, 0x59, 0xf9, 0x51, 0x98, 0x09, - 0x18, 0x6d, 0x37, 0x29, 0xb7, 0x77, 0xe5, 0xe7, 0x2b, 0xc8, 0x5d, 0xc0, 0x67, 0x0e, 0x0f, 0x16, - 0x66, 0x30, 0x49, 0xc0, 0x34, 0x1f, 0xf9, 0x38, 0x9c, 0x52, 0x91, 0xa9, 0x75, 0x7a, 0x5f, 0x1d, - 0x6f, 0x90, 0x1d, 0x56, 0x56, 0x39, 0xcd, 0x66, 0x9a, 0x84, 0x59, 0x5e, 0x31, 0xac, 0x55, 0xd1, - 0x56, 0x48, 0x3b, 0xaa, 0x31, 0xb2, 0x17, 0x66, 0xd4, 0xb0, 0x6e, 0x66, 0x68, 0x38, 0xc4, 0x4d, - 0x28, 0x34, 0x44, 0x8b, 0x36, 0x9d, 0x1e, 0xf3, 0x07, 0xe6, 0xae, 0x98, 0xa3, 0x26, 0x60, 0xe5, - 0xea, 0x8e, 0x31, 0x0c, 0x26, 0x31, 0xad, 0xbf, 0x2b, 0xc0, 0x74, 0xdc, 0x5f, 0x27, 0x9e, 0xeb, - 0xda, 0x49, 0xe7, 0xba, 0x96, 0x26, 0x1e, 0x0e, 0x23, 0xb2, 0x5b, 0xbf, 0x5e, 0x8d, 0x5f, 0x4b, - 0xe6, 0xb3, 0xb6, 0x61, 0xde, 0xc9, 0x4d, 0xf1, 0x24, 0xb4, 0x4d, 0xb4, 0x5b, 0xf0, 0xc6, 0x48, - 0x4e, 0x7c, 0x08, 0x0a, 0x19, 0x40, 0x6d, 0x8f, 0x05, 0xdc, 0xb1, 0x99, 0x79, 0xbf, 0xeb, 0x13, - 0x5b, 0x47, 0x6a, 0xa7, 0x44, 0xdc, 0xa7, 0x77, 0xb4, 0x00, 0x8c, 0x44, 0x91, 0x6d, 0xa8, 0xb0, - 0x76, 0x87, 0x99, 0x13, 0x2a, 0x13, 0x9e, 0xe6, 0x8e, 0xfa, 0x53, 0x3c, 0x85, 0xa8, 0xa0, 0x49, - 0x08, 0x75, 0xd7, 0xb8, 0xef, 0x7a, 0x1c, 0x8e, 0x6f, 0xeb, 0x44, 0x81, 0x80, 0x78, 0xb7, 0x6e, - 0x54, 0x84, 0xb1, 0x1c, 0xd2, 0x8d, 0xae, 0x98, 0xa8, 0x1c, 0x93, 0xf2, 0x78, 0xc8, 0x25, 0x13, - 0x21, 0xd4, 0xef, 0x51, 0xce, 0x82, 0x1e, 0x0d, 0xba, 0xda, 0xf0, 0x1f, 0xff, 0x0d, 0xef, 0x1a, - 0xa4, 0xf8, 0x0d, 0xa3, 0x22, 0x8c, 0xe5, 0x10, 0x1f, 0xea, 0x5c, 0x5b, 0xb2, 0xe6, 0xe0, 0xed, - 0xf8, 0x42, 0x8d, 0x4d, 0x1c, 0xaa, 0x90, 0x7c, 0xf4, 0x88, 0xb1, 0x0c, 0xeb, 0x41, 0x29, 0x56, - 0x8f, 0xef, 0x75, 0x72, 0xf3, 0xa5, 0x74, 0x72, 0xf3, 0x62, 0x36, 0xb9, 0x99, 0x89, 0xc6, 0x1c, - 0x3d, 0xbd, 0x49, 0xa1, 0xe1, 0xd2, 0x90, 0x6f, 0xf5, 0xdb, 0x94, 0xeb, 0xc8, 0x78, 0xe3, 0xea, - 0xff, 0x7b, 0x3c, 0xed, 0x25, 0xf4, 0x61, 0x1c, 0x74, 0x59, 0x8b, 0x61, 0x30, 0x89, 0x49, 0x5e, - 0x84, 0xc6, 0x9e, 0x9c, 0x91, 0xea, 0xd8, 0x49, 0x45, 0xaa, 0x73, 0xa9, 0x61, 0xef, 0xc4, 0xc5, - 0x98, 0xe4, 0x11, 0x55, 0x94, 0x25, 0x10, 0x9f, 0xc2, 0xd7, 0x55, 0x5a, 0x71, 0x31, 0x26, 0x79, - 0x64, 0x96, 0xc5, 0xf1, 0xba, 0xaa, 0xc2, 0x94, 0xac, 0xa0, 0xb2, 0x2c, 0xa6, 0x10, 0x63, 0x3a, - 0xb9, 0x0c, 0xb5, 0x41, 0x7b, 0x47, 0xf1, 0xd6, 0x24, 0xaf, 0xb4, 0xbf, 0xb6, 0x56, 0x56, 0xf5, - 0x31, 0x18, 0x43, 0xb5, 0xfe, 0xbd, 0x00, 0x64, 0x38, 0x1d, 0x4f, 0x76, 0xa1, 0xea, 0xc9, 0xa8, - 0xca, 0xc4, 0x97, 0x5f, 0x24, 0x82, 0x33, 0x6a, 0x8e, 0xe9, 0x02, 0x8d, 0x4f, 0x3c, 0xa8, 0xb1, - 0xfb, 0x9c, 0x05, 0x1e, 0x75, 0xb5, 0xe9, 0x71, 0x3c, 0x17, 0x6d, 0x28, 0x83, 0x53, 0x23, 0x63, - 0x24, 0xc3, 0xfa, 0x7e, 0x11, 0x1a, 0x09, 0xbe, 0x47, 0x39, 0x2b, 0x72, 0x73, 0xad, 0x0a, 0x66, - 0x6c, 0x05, 0xae, 0x1e, 0xa6, 0x89, 0xcd, 0xb5, 0x9a, 0x84, 0x6b, 0x98, 0xe4, 0x23, 0x57, 0x01, - 0x7a, 0x34, 0xe4, 0x2c, 0x90, 0x4b, 0x49, 0x66, 0x4b, 0xeb, 0x7a, 0x44, 0xc1, 0x04, 0x17, 0xb9, - 0xa4, 0xaf, 0x4a, 0x29, 0xa7, 0x8f, 0x25, 0x8e, 0xb8, 0x07, 0xa5, 0x72, 0x0c, 0xf7, 0xa0, 0x90, - 0x0e, 0x9c, 0x36, 0xad, 0x36, 0xd4, 0xa3, 0x1d, 0x5a, 0x53, 0xc6, 0x78, 0x06, 0x02, 0x87, 0x40, - 0xad, 0x6f, 0x16, 0x60, 0x26, 0xe5, 0x4a, 0xab, 0x03, 0x85, 0x66, 0x33, 0x49, 0xea, 0x40, 0x61, - 0x62, 0x0f, 0xc8, 0x0b, 0x50, 0x55, 0x1d, 0xa4, 0x3b, 0x3e, 0x52, 0x23, 0xaa, 0x0b, 0x51, 0x53, - 0x85, 0x42, 0xd0, 0xc1, 0xba, 0xac, 0x42, 0xd0, 0xd1, 0x3c, 0x34, 0x74, 0xf2, 0x21, 0xa8, 0x99, - 0xd6, 0xe9, 0x9e, 0x8e, 0x6f, 0xd5, 0xd1, 0xe5, 0x18, 0x71, 0x58, 0x5f, 0x2b, 0xe9, 0xe9, 0xa1, - 0x72, 0x6f, 0xc6, 0xc3, 0xfd, 0x79, 0x61, 0x84, 0x45, 0x63, 0xe8, 0x58, 0x2f, 0x88, 0x89, 0xc6, - 0x56, 0xa2, 0x10, 0x93, 0xd2, 0x44, 0xa7, 0x24, 0x76, 0xc5, 0xd4, 0x93, 0xba, 0x55, 0xee, 0x62, - 0xd1, 0x54, 0x7d, 0x50, 0x61, 0x28, 0xfd, 0x90, 0x3c, 0xa8, 0x10, 0x13, 0xb3, 0xa9, 0x87, 0xeb, - 0x70, 0x46, 0x98, 0x84, 0xab, 0x81, 0xdf, 0x6b, 0xb2, 0x8e, 0xe3, 0x79, 0x8e, 0xd7, 0xd1, 0x79, - 0xc5, 0x28, 0x7f, 0x81, 0x59, 0x06, 0x1c, 0xae, 0x63, 0xbc, 0xf3, 0xca, 0x71, 0x7b, 0xe7, 0xd6, - 0x97, 0x8b, 0x20, 0xb3, 0x09, 0xe4, 0xa3, 0x50, 0xef, 0x31, 0x7b, 0x97, 0x7a, 0x4e, 0x68, 0x4e, - 0x6e, 0x0b, 0xdf, 0xb6, 0xbe, 0x6e, 0x0a, 0x1f, 0x88, 0x6f, 0xbb, 0xd4, 0x5a, 0x93, 0xfb, 0x49, - 0x62, 0x5e, 0x62, 0x43, 0xb5, 0x13, 0x86, 0xb4, 0xef, 0x4c, 0x7c, 0xbd, 0x9b, 0x3a, 0x5b, 0xab, - 0xf4, 0x9b, 0xfa, 0x8d, 0x1a, 0x9a, 0xd8, 0x50, 0xe9, 0xbb, 0xd4, 0xf1, 0xb4, 0xb3, 0xd3, 0x9c, - 0x28, 0x87, 0xb2, 0x21, 0x90, 0x54, 0x14, 0x47, 0xfe, 0x44, 0x85, 0x6d, 0xfd, 0x67, 0x01, 0xea, - 0x11, 0x9d, 0x6c, 0x01, 0x08, 0x75, 0xa1, 0xcf, 0x87, 0x1e, 0xe9, 0xe6, 0x25, 0xe9, 0x8f, 0x6e, - 0x45, 0x95, 0x31, 0x01, 0x94, 0x73, 0x80, 0xb6, 0x78, 0xdc, 0x07, 0x68, 0xaf, 0x40, 0x7d, 0x97, - 0x7a, 0xed, 0x70, 0x97, 0x76, 0x95, 0xd6, 0xac, 0xc5, 0xc6, 0xd2, 0x6b, 0x86, 0x80, 0x31, 0x8f, - 0xf5, 0x07, 0x65, 0x50, 0x57, 0x76, 0x89, 0x79, 0xdd, 0x76, 0x42, 0x95, 0xff, 0x2e, 0xc8, 0x9a, - 0xd1, 0xbc, 0x5e, 0xd1, 0xe5, 0x18, 0x71, 0x90, 0xf3, 0x50, 0xea, 0x39, 0x9e, 0x0e, 0xfb, 0xcb, - 0x71, 0xb5, 0xee, 0x78, 0x28, 0xca, 0x24, 0x89, 0xde, 0xd7, 0x29, 0x5c, 0x45, 0xa2, 0xf7, 0x51, - 0x94, 0x09, 0xe7, 0xcf, 0xf5, 0xfd, 0xee, 0x36, 0xb5, 0xbb, 0x26, 0x35, 0x55, 0x96, 0xab, 0xab, - 0x74, 0xfe, 0xd6, 0xd2, 0x24, 0xcc, 0xf2, 0x8a, 0xea, 0xb6, 0xef, 0xbb, 0x6d, 0xff, 0x9e, 0x67, - 0xaa, 0x57, 0xe2, 0xea, 0xcb, 0x69, 0x12, 0x66, 0x79, 0xc9, 0x16, 0x3c, 0xfb, 0x0e, 0x0b, 0x7c, - 0xad, 0xd1, 0x5a, 0x2e, 0x63, 0x7d, 0x03, 0xa3, 0x0c, 0x08, 0x99, 0x6f, 0xfe, 0x74, 0x3e, 0x0b, - 0x8e, 0xaa, 0x2b, 0xd3, 0xd8, 0x34, 0xe8, 0x30, 0xbe, 0x11, 0xf8, 0x36, 0x0b, 0x43, 0xc7, 0xeb, - 0x18, 0xd8, 0xa9, 0x18, 0x76, 0x33, 0x9f, 0x05, 0x47, 0xd5, 0x25, 0x6f, 0xc0, 0x9c, 0x22, 0x29, - 0xc3, 0x62, 0x69, 0x8f, 0x3a, 0x2e, 0xdd, 0x76, 0x5c, 0x87, 0xef, 0xcb, 0x4d, 0x1f, 0x33, 0x2a, - 0x36, 0xbf, 0x39, 0x82, 0x07, 0x47, 0xd6, 0x96, 0x77, 0x6a, 0xea, 0xcc, 0xcc, 0x06, 0x0b, 0xe4, - 0xd7, 0x97, 0x61, 0x5e, 0xed, 0x43, 0x63, 0x86, 0x86, 0x43, 0xdc, 0xd6, 0x6f, 0x94, 0x40, 0x5e, - 0x92, 0x28, 0x94, 0x93, 0xeb, 0x1b, 0xfd, 0x3d, 0xbe, 0x72, 0x5a, 0xf3, 0x3b, 0x6a, 0xa4, 0xac, - 0xf9, 0x1d, 0x14, 0x88, 0x62, 0xd6, 0x77, 0xe9, 0x4e, 0x97, 0xea, 0x29, 0x32, 0xfe, 0xac, 0x8f, - 0x72, 0xfa, 0x6a, 0xd6, 0xcb, 0x47, 0x54, 0xd8, 0xc2, 0x53, 0xd8, 0x36, 0xb7, 0x98, 0x4d, 0xac, - 0x5e, 0xa2, 0xfb, 0xd0, 0x94, 0x59, 0x19, 0x3d, 0x62, 0x2c, 0x43, 0x28, 0xcc, 0x41, 0x5b, 0x5e, - 0x56, 0x59, 0x9e, 0x50, 0x61, 0x6e, 0xad, 0xc8, 0x77, 0x92, 0x0a, 0x53, 0xfd, 0x46, 0x0d, 0x6d, - 0xfd, 0x61, 0x01, 0x66, 0x5a, 0xae, 0xd3, 0x76, 0xbc, 0xce, 0xc9, 0xdd, 0x45, 0x41, 0x6e, 0x43, - 0x25, 0x74, 0x9d, 0x36, 0x1b, 0xf3, 0x98, 0xba, 0xfc, 0x18, 0xa2, 0x95, 0x0c, 0x15, 0x8e, 0xf5, - 0x8d, 0x0a, 0xe8, 0x9b, 0x3d, 0xc9, 0x00, 0xea, 0x1d, 0x73, 0x66, 0x5e, 0x37, 0xf9, 0xb5, 0x09, - 0xce, 0x56, 0xa5, 0x4e, 0xdf, 0xab, 0xaf, 0x13, 0x15, 0x62, 0x2c, 0x89, 0xb0, 0xf4, 0x98, 0x5b, - 0x99, 0x70, 0xcc, 0x29, 0x71, 0xc3, 0xa3, 0x8e, 0x42, 0x79, 0x97, 0xf3, 0xbe, 0x1e, 0x70, 0xe3, - 0xef, 0xc9, 0x8f, 0xb7, 0xdb, 0xab, 0xb8, 0xb8, 0x78, 0x46, 0x09, 0x2d, 0x44, 0x78, 0x34, 0xba, - 0x74, 0x6d, 0x79, 0xa2, 0xc0, 0x7b, 0x52, 0x84, 0x78, 0x46, 0x09, 0x4d, 0xbe, 0x50, 0x80, 0xe9, - 0x20, 0x61, 0xd8, 0x69, 0x03, 0x65, 0xc2, 0x3d, 0xcd, 0x29, 0x2b, 0x51, 0xed, 0xd9, 0x49, 0x96, - 0x63, 0x4a, 0xa4, 0xb0, 0x22, 0x79, 0x40, 0xbd, 0x70, 0xc7, 0x0f, 0x7a, 0x2c, 0xd0, 0x86, 0xf7, - 0xea, 0x04, 0x73, 0x6a, 0x33, 0x46, 0x53, 0xa1, 0xcc, 0x54, 0x11, 0x26, 0xa5, 0x59, 0x3d, 0xd0, - 0xbe, 0x38, 0xb1, 0x53, 0xd7, 0xd6, 0xa8, 0xed, 0x0b, 0x57, 0x1e, 0x6f, 0x3e, 0x44, 0x37, 0xae, - 0x24, 0x4e, 0x16, 0xe7, 0xde, 0x4f, 0x63, 0xfd, 0x43, 0x11, 0x84, 0xe9, 0xa6, 0x0e, 0xca, 0xc9, - 0x3b, 0xa1, 0x58, 0xab, 0xeb, 0xf4, 0xef, 0xb0, 0xc0, 0xd9, 0xd9, 0xd7, 0x0b, 0x76, 0xe2, 0xa0, - 0x5c, 0x96, 0x03, 0x73, 0x6a, 0x91, 0x37, 0x61, 0xda, 0xa6, 0xcb, 0x2c, 0xe0, 0xe3, 0x98, 0x23, - 0xf2, 0xe3, 0x2c, 0x2f, 0xc5, 0xd5, 0x31, 0x05, 0x26, 0x8c, 0x28, 0x3b, 0x86, 0x2e, 0x1d, 0xd9, - 0x88, 0x4a, 0x00, 0x27, 0x80, 0x08, 0x42, 0xbd, 0x2b, 0x58, 0x25, 0x6a, 0xf9, 0x28, 0xa8, 0x72, - 0xe2, 0xdf, 0x34, 0x75, 0x31, 0x86, 0xb1, 0x3c, 0x98, 0x49, 0xdd, 0x7e, 0x43, 0x3e, 0x06, 0x35, - 0xbf, 0x9f, 0xd0, 0x3f, 0x75, 0x99, 0xb0, 0xaf, 0xdd, 0xd6, 0x65, 0x0f, 0x0e, 0x16, 0x66, 0xd6, - 0xfc, 0x8e, 0x63, 0x9b, 0x02, 0x8c, 0xd8, 0x89, 0x05, 0x55, 0xb9, 0xb9, 0xc2, 0xdc, 0x7d, 0x23, - 0x75, 0xa7, 0xbc, 0x17, 0x23, 0x44, 0x4d, 0xb1, 0xfe, 0xb5, 0x00, 0x71, 0x24, 0x89, 0x84, 0x50, - 0x6d, 0xcb, 0x3b, 0x32, 0xb4, 0xaa, 0x1b, 0x3f, 0x22, 0x97, 0xbe, 0x8d, 0x4b, 0x19, 0x8c, 0xe9, - 0x32, 0xd4, 0xa2, 0x48, 0x07, 0x4a, 0x6f, 0xfb, 0xdb, 0x13, 0x6b, 0xba, 0xc4, 0xf6, 0x47, 0x15, - 0x7e, 0x49, 0x14, 0xa0, 0x90, 0x60, 0xfd, 0x52, 0x11, 0x1a, 0x89, 0x39, 0x34, 0xf1, 0xdd, 0x41, - 0xf7, 0x33, 0x77, 0x07, 0x6d, 0x8c, 0xef, 0x11, 0xc5, 0xad, 0x3a, 0xe9, 0xeb, 0x83, 0xfe, 0xaa, - 0x08, 0xa5, 0xad, 0x95, 0x55, 0x61, 0x70, 0x44, 0xdb, 0x20, 0x27, 0xce, 0x6e, 0xc7, 0xd7, 0xda, - 0xca, 0x91, 0x1d, 0x3d, 0x62, 0x2c, 0x83, 0xec, 0xc2, 0xd4, 0xf6, 0xc0, 0x71, 0xb9, 0xe3, 0x4d, - 0xbc, 0xe9, 0xd6, 0x5c, 0xb5, 0xa4, 0x37, 0xf4, 0x29, 0x54, 0x34, 0xf0, 0xa4, 0x03, 0x53, 0x1d, - 0x75, 0xe8, 0x4e, 0xcf, 0xf5, 0x57, 0xc7, 0x5f, 0xb1, 0x15, 0x8e, 0x12, 0xa4, 0x1f, 0xd0, 0xa0, - 0x5b, 0x9f, 0x03, 0x6d, 0xf0, 0x90, 0xf0, 0x64, 0x7a, 0x33, 0x72, 0x98, 0xf2, 0x7a, 0xd4, 0xfa, - 0xb7, 0x02, 0xa4, 0x57, 0x85, 0xf7, 0xfe, 0xa3, 0x76, 0xb3, 0x1f, 0x75, 0xe5, 0x38, 0xe6, 0x40, - 0xfe, 0x77, 0xb5, 0xfe, 0xbc, 0x08, 0x55, 0x7d, 0xdf, 0xfb, 0xc9, 0xa7, 0x50, 0x59, 0x2a, 0x85, - 0xba, 0x3c, 0xe1, 0x45, 0xa8, 0x23, 0x13, 0xa8, 0xbd, 0x4c, 0x02, 0x75, 0xd2, 0x1b, 0x57, 0x1f, - 0x91, 0x3e, 0xfd, 0x9b, 0x02, 0xcc, 0x2a, 0xc6, 0x1b, 0x5e, 0xc8, 0xa9, 0x67, 0x4b, 0x47, 0x40, - 0x85, 0xb3, 0x27, 0xce, 0x0f, 0xe8, 0x5c, 0x96, 0x5a, 0x66, 0xe4, 0x6f, 0xd4, 0xd0, 0xc2, 0xa3, - 0xdf, 0xf5, 0x43, 0x2e, 0xd5, 0x6d, 0x31, 0x1d, 0xa9, 0x7b, 0x4d, 0x97, 0x63, 0xc4, 0x91, 0x0d, - 0x01, 0x56, 0x46, 0x87, 0x00, 0xad, 0xdf, 0x2b, 0xc2, 0x74, 0xea, 0x9e, 0xdd, 0xb1, 0xb3, 0xc1, - 0x99, 0x64, 0x6c, 0xf1, 0xf8, 0x93, 0xb1, 0x79, 0x09, 0xe7, 0xd2, 0x84, 0x09, 0xe7, 0xf2, 0x51, - 0x12, 0xce, 0xd6, 0xb7, 0x0b, 0x00, 0xa6, 0xb7, 0x4e, 0x3c, 0x17, 0xdc, 0x4e, 0xe7, 0x82, 0x27, - 0x1e, 0x57, 0xf9, 0x99, 0xe0, 0x3f, 0xad, 0x98, 0x57, 0x92, 0x79, 0xe0, 0x77, 0x0b, 0x30, 0x4b, - 0x53, 0xb9, 0xd5, 0x89, 0x4d, 0x99, 0x4c, 0xaa, 0x36, 0xba, 0x11, 0x3e, 0x5d, 0x8e, 0x19, 0xb1, - 0xe4, 0x65, 0x98, 0xee, 0xeb, 0x84, 0xd7, 0xad, 0x78, 0xd8, 0x47, 0x07, 0x40, 0x36, 0x12, 0x34, - 0x4c, 0x71, 0x3e, 0x22, 0x97, 0x5d, 0x3a, 0x96, 0x5c, 0x76, 0x72, 0xc3, 0x6c, 0xf9, 0xa1, 0x1b, - 0x66, 0xf7, 0xa0, 0xbe, 0x13, 0xf8, 0x3d, 0x99, 0x2e, 0xd6, 0x77, 0xb5, 0x5e, 0x9b, 0x60, 0x4d, - 0x89, 0x6f, 0x29, 0x8f, 0x57, 0xb7, 0x55, 0x83, 0x8f, 0xb1, 0x28, 0xd2, 0x87, 0x29, 0xee, 0x2b, - 0xa9, 0xd5, 0xe3, 0x94, 0x1a, 0xe9, 0x92, 0x4d, 0x85, 0x8e, 0x46, 0x4c, 0x3a, 0x45, 0x3c, 0xf5, - 0xde, 0xa4, 0x88, 0xad, 0xbf, 0x8f, 0x14, 0x58, 0x2b, 0x73, 0x46, 0xb4, 0x30, 0xe2, 0x8c, 0xa8, - 0xbe, 0x5c, 0x21, 0x99, 0x44, 0x7d, 0x01, 0xaa, 0x01, 0xa3, 0xa1, 0xef, 0xe9, 0x6b, 0x4a, 0x22, - 0xf5, 0x8f, 0xb2, 0x14, 0x35, 0x35, 0x99, 0x6c, 0x2d, 0x3e, 0x22, 0xd9, 0xfa, 0xa1, 0xc4, 0x00, - 0x51, 0xbb, 0x5a, 0xa2, 0xb9, 0x9e, 0x33, 0x48, 0x64, 0x26, 0x46, 0xff, 0xcd, 0x53, 0x25, 0x9b, - 0x89, 0xd1, 0x7f, 0xc1, 0x14, 0x71, 0x90, 0x36, 0x4c, 0xbb, 0x34, 0xe4, 0x32, 0x80, 0xd7, 0x5e, - 0xe2, 0x63, 0x64, 0x72, 0xa3, 0x69, 0xb4, 0x96, 0xc0, 0xc1, 0x14, 0xaa, 0xf5, 0x6b, 0x05, 0x88, - 0xbb, 0xfc, 0x88, 0x31, 0xe5, 0x37, 0xa0, 0xd6, 0xa3, 0xf7, 0x57, 0x98, 0x4b, 0xf7, 0x27, 0xb9, - 0xfc, 0x70, 0x5d, 0x63, 0x60, 0x84, 0x66, 0x1d, 0x14, 0x40, 0x5f, 0xd8, 0x40, 0x18, 0x54, 0x76, - 0x9c, 0xfb, 0xba, 0x3d, 0x93, 0x98, 0x4e, 0x89, 0xcb, 0x5e, 0x55, 0x90, 0x47, 0x16, 0xa0, 0x42, - 0x27, 0x3d, 0x98, 0x0a, 0x55, 0x0c, 0x4e, 0xbf, 0xca, 0xf8, 0x61, 0x89, 0x54, 0x2c, 0x4f, 0x5f, - 0xbf, 0xa0, 0x8a, 0xd0, 0xc8, 0x68, 0x2e, 0x7e, 0xeb, 0xbb, 0x17, 0x9f, 0xfa, 0xf6, 0x77, 0x2f, - 0x3e, 0xf5, 0x9d, 0xef, 0x5e, 0x7c, 0xea, 0xf3, 0x87, 0x17, 0x0b, 0xdf, 0x3a, 0xbc, 0x58, 0xf8, - 0xf6, 0xe1, 0xc5, 0xc2, 0x77, 0x0e, 0x2f, 0x16, 0xfe, 0xf9, 0xf0, 0x62, 0xe1, 0x57, 0xff, 0xe5, - 0xe2, 0x53, 0x9f, 0xae, 0x19, 0xcc, 0xff, 0x09, 0x00, 0x00, 0xff, 0xff, 0x97, 0xe6, 0x55, 0xbf, - 0x56, 0x6e, 0x00, 0x00, + // 6555 bytes of a gzipped FileDescriptorProto + 0x1f, 0x8b, 0x08, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0xff, 0xec, 0x7d, 0x5d, 0x6c, 0x24, 0xd9, + 0x55, 0xf0, 0xf6, 0x9f, 0xdd, 0x7d, 0xda, 0xf6, 0xcc, 0xdc, 0xf9, 0xd9, 0x1e, 0xef, 0xec, 0xf4, + 0xa4, 0xf2, 0xed, 0x7e, 0x93, 0xef, 0x4b, 0x3c, 0xdf, 0xfa, 0xdb, 0x90, 0x0d, 0x90, 0xec, 0xba, + 0xed, 0xb1, 0xd7, 0x3b, 0xf6, 0x8c, 0x73, 0xda, 0x9e, 0xd9, 0x64, 0x21, 0x4b, 0xb9, 0xfa, 0xba, + 0x5d, 0xdb, 0xd5, 0x55, 0x9d, 0xaa, 0xdb, 0x9e, 0xf1, 0x42, 0x44, 0x42, 0x1e, 0x36, 0x51, 0x40, + 0x41, 0xf0, 0x12, 0x81, 0x02, 0x42, 0x42, 0xe2, 0x01, 0x45, 0x42, 0x82, 0xf0, 0x00, 0x42, 0x84, + 0x17, 0x14, 0x78, 0x80, 0x3c, 0x20, 0x25, 0x28, 0xc8, 0x22, 0xe6, 0x89, 0x07, 0xa2, 0x88, 0x48, + 0x28, 0x1a, 0x21, 0x81, 0xee, 0x5f, 0xfd, 0x75, 0xf5, 0x8c, 0xdd, 0x6d, 0x6f, 0x26, 0x22, 0x6f, + 0x5d, 0xe7, 0x9c, 0x7b, 0xce, 0xad, 0x5b, 0xf7, 0x9e, 0x7b, 0xfe, 0xee, 0x6d, 0x58, 0x69, 0xdb, + 0x6c, 0xb7, 0xbf, 0x3d, 0x67, 0x79, 0xdd, 0x1b, 0x6e, 0xbf, 0x6b, 0xf6, 0x7c, 0xef, 0x2d, 0xf1, + 0x63, 0xc7, 0xf1, 0xee, 0xdf, 0xe8, 0x75, 0xda, 0x37, 0xcc, 0x9e, 0x1d, 0x44, 0x90, 0xbd, 0x17, + 0x4c, 0xa7, 0xb7, 0x6b, 0xbe, 0x70, 0xa3, 0x4d, 0x5d, 0xea, 0x9b, 0x8c, 0xb6, 0xe6, 0x7a, 0xbe, + 0xc7, 0x3c, 0xf2, 0xa1, 0x88, 0xd1, 0x9c, 0x66, 0x34, 0xa7, 0x9b, 0xcd, 0xf5, 0x3a, 0xed, 0x39, + 0xce, 0x28, 0x82, 0x68, 0x46, 0xb3, 0x1f, 0x88, 0xf5, 0xa0, 0xed, 0xb5, 0xbd, 0x1b, 0x82, 0xdf, + 0x76, 0x7f, 0x47, 0x3c, 0x89, 0x07, 0xf1, 0x4b, 0xca, 0x99, 0x35, 0x3a, 0x2f, 0x05, 0x73, 0xb6, + 0xc7, 0xbb, 0x75, 0xc3, 0xf2, 0x7c, 0x7a, 0x63, 0x6f, 0xa0, 0x2f, 0xb3, 0x2f, 0x46, 0x34, 0x5d, + 0xd3, 0xda, 0xb5, 0x5d, 0xea, 0xef, 0xeb, 0x77, 0xb9, 0xe1, 0xd3, 0xc0, 0xeb, 0xfb, 0x16, 0x3d, + 0x56, 0xab, 0xe0, 0x46, 0x97, 0x32, 0x33, 0x4b, 0xd6, 0x8d, 0x61, 0xad, 0xfc, 0xbe, 0xcb, 0xec, + 0xee, 0xa0, 0x98, 0x9f, 0x7a, 0x5c, 0x83, 0xc0, 0xda, 0xa5, 0x5d, 0x33, 0xdd, 0xce, 0xf8, 0x4e, + 0x05, 0xce, 0x2f, 0x6c, 0x07, 0xcc, 0x37, 0x2d, 0xb6, 0xe1, 0xb5, 0x36, 0x69, 0xb7, 0xe7, 0x98, + 0x8c, 0x92, 0x0e, 0x94, 0x79, 0xdf, 0x5a, 0x26, 0x33, 0x6b, 0xb9, 0x6b, 0xb9, 0xeb, 0xd5, 0xf9, + 0x85, 0xb9, 0x11, 0xbf, 0xc5, 0xdc, 0xba, 0x62, 0xd4, 0x98, 0x3a, 0x3c, 0xa8, 0x97, 0xf5, 0x13, + 0x86, 0x02, 0xc8, 0x97, 0x73, 0x30, 0xe5, 0x7a, 0x2d, 0xda, 0xa4, 0x0e, 0xb5, 0x98, 0xe7, 0xd7, + 0xf2, 0xd7, 0x0a, 0xd7, 0xab, 0xf3, 0x9f, 0x1c, 0x59, 0x62, 0xc6, 0x1b, 0xcd, 0xdd, 0x8e, 0x09, + 0xb8, 0xe9, 0x32, 0x7f, 0xbf, 0x71, 0xe1, 0x1b, 0x07, 0xf5, 0xa7, 0x0e, 0x0f, 0xea, 0x53, 0x71, + 0x14, 0x26, 0x7a, 0x42, 0xb6, 0xa0, 0xca, 0x3c, 0x87, 0x0f, 0x99, 0xed, 0xb9, 0x41, 0xad, 0x20, + 0x3a, 0x76, 0x75, 0x4e, 0x8e, 0x36, 0x17, 0x3f, 0xc7, 0xa7, 0xcb, 0xdc, 0xde, 0x0b, 0x73, 0x9b, + 0x21, 0x59, 0xe3, 0xbc, 0x62, 0x5c, 0x8d, 0x60, 0x01, 0xc6, 0xf9, 0x10, 0x0a, 0x67, 0x02, 0x6a, + 0xf5, 0x7d, 0x9b, 0xed, 0x2f, 0x7a, 0x2e, 0xa3, 0x0f, 0x58, 0xad, 0x28, 0x46, 0xf9, 0xf9, 0x2c, + 0xd6, 0x1b, 0x5e, 0xab, 0x99, 0xa4, 0x6e, 0x9c, 0x3f, 0x3c, 0xa8, 0x9f, 0x49, 0x01, 0x31, 0xcd, + 0x93, 0xb8, 0x70, 0xd6, 0xee, 0x9a, 0x6d, 0xba, 0xd1, 0x77, 0x9c, 0x26, 0xb5, 0x7c, 0xca, 0x82, + 0x5a, 0x49, 0xbc, 0xc2, 0xf5, 0x2c, 0x39, 0x6b, 0x9e, 0x65, 0x3a, 0x77, 0xb6, 0xdf, 0xa2, 0x16, + 0x43, 0xba, 0x43, 0x7d, 0xea, 0x5a, 0xb4, 0x51, 0x53, 0x2f, 0x73, 0x76, 0x35, 0xc5, 0x09, 0x07, + 0x78, 0x93, 0x15, 0x38, 0xd7, 0xf3, 0x6d, 0x4f, 0x74, 0xc1, 0x31, 0x83, 0xe0, 0xb6, 0xd9, 0xa5, + 0xb5, 0x89, 0x6b, 0xb9, 0xeb, 0x95, 0xc6, 0x65, 0xc5, 0xe6, 0xdc, 0x46, 0x9a, 0x00, 0x07, 0xdb, + 0x90, 0xeb, 0x50, 0xd6, 0xc0, 0xda, 0xe4, 0xb5, 0xdc, 0xf5, 0x92, 0x9c, 0x3b, 0xba, 0x2d, 0x86, + 0x58, 0xb2, 0x0c, 0x65, 0x73, 0x67, 0xc7, 0x76, 0x39, 0x65, 0x59, 0x0c, 0xe1, 0x95, 0xac, 0x57, + 0x5b, 0x50, 0x34, 0x92, 0x8f, 0x7e, 0xc2, 0xb0, 0x2d, 0x79, 0x0d, 0x48, 0x40, 0xfd, 0x3d, 0xdb, + 0xa2, 0x0b, 0x96, 0xe5, 0xf5, 0x5d, 0x26, 0xfa, 0x5e, 0x11, 0x7d, 0x9f, 0x55, 0x7d, 0x27, 0xcd, + 0x01, 0x0a, 0xcc, 0x68, 0x45, 0x5e, 0x81, 0xb3, 0x6a, 0xd9, 0x45, 0xa3, 0x00, 0x82, 0xd3, 0x05, + 0x3e, 0x90, 0x98, 0xc2, 0xe1, 0x00, 0x35, 0x69, 0xc1, 0x15, 0xb3, 0xcf, 0xbc, 0x2e, 0x67, 0x99, + 0x14, 0xba, 0xe9, 0x75, 0xa8, 0x5b, 0xab, 0x5e, 0xcb, 0x5d, 0x2f, 0x37, 0xae, 0x1d, 0x1e, 0xd4, + 0xaf, 0x2c, 0x3c, 0x82, 0x0e, 0x1f, 0xc9, 0x85, 0xdc, 0x81, 0x4a, 0xcb, 0x0d, 0x36, 0x3c, 0xc7, + 0xb6, 0xf6, 0x6b, 0x53, 0xa2, 0x83, 0x2f, 0xa8, 0x57, 0xad, 0x2c, 0xdd, 0x6e, 0x4a, 0xc4, 0xc3, + 0x83, 0xfa, 0x95, 0x41, 0xed, 0x38, 0x17, 0xe2, 0x31, 0xe2, 0x41, 0xd6, 0x05, 0xc3, 0x45, 0xcf, + 0xdd, 0xb1, 0xdb, 0xb5, 0x69, 0xf1, 0x35, 0xae, 0x0d, 0x99, 0xd0, 0x4b, 0xb7, 0x9b, 0x92, 0xae, + 0x31, 0xad, 0xc4, 0xc9, 0x47, 0x8c, 0x38, 0xcc, 0xbe, 0x0c, 0xe7, 0x06, 0x56, 0x2d, 0x39, 0x0b, + 0x85, 0x0e, 0xdd, 0x17, 0x4a, 0xa9, 0x82, 0xfc, 0x27, 0xb9, 0x00, 0xa5, 0x3d, 0xd3, 0xe9, 0xd3, + 0x5a, 0x5e, 0xc0, 0xe4, 0xc3, 0x4f, 0xe7, 0x5f, 0xca, 0x19, 0xdf, 0xab, 0xc2, 0x8c, 0xd6, 0x05, + 0x77, 0xa9, 0xcf, 0xe8, 0x03, 0x72, 0x0d, 0x8a, 0x2e, 0xff, 0x1e, 0xa2, 0x7d, 0x63, 0x4a, 0xbd, + 0x6e, 0x51, 0x7c, 0x07, 0x81, 0x21, 0x16, 0x4c, 0x48, 0x5d, 0x2e, 0xf8, 0x55, 0xe7, 0x5f, 0x1e, + 0x59, 0x0d, 0x35, 0x05, 0x9b, 0x06, 0x1c, 0x1e, 0xd4, 0x27, 0xe4, 0x6f, 0x54, 0xac, 0xc9, 0x1b, + 0x50, 0x0c, 0x6c, 0xb7, 0x53, 0x2b, 0x08, 0x11, 0x1f, 0x19, 0x5d, 0x84, 0xed, 0x76, 0x1a, 0x65, + 0xfe, 0x06, 0xfc, 0x17, 0x0a, 0xa6, 0xe4, 0x1e, 0x14, 0xfa, 0xad, 0x1d, 0xa5, 0x51, 0x7e, 0x76, + 0x64, 0xde, 0x5b, 0x4b, 0xcb, 0x8d, 0xc9, 0xc3, 0x83, 0x7a, 0x61, 0x6b, 0x69, 0x19, 0x39, 0x47, + 0xf2, 0xa5, 0x1c, 0x9c, 0xb3, 0x3c, 0x97, 0x99, 0x7c, 0x7f, 0xd1, 0x9a, 0xb5, 0x56, 0x12, 0x72, + 0x5e, 0x1b, 0x59, 0xce, 0x62, 0x9a, 0x63, 0xe3, 0x22, 0x57, 0x14, 0x03, 0x60, 0x1c, 0x94, 0x4d, + 0x7e, 0x3b, 0x07, 0x17, 0xf9, 0x02, 0x1e, 0x20, 0x16, 0x6a, 0xe7, 0x64, 0x7b, 0x75, 0xf9, 0xf0, + 0xa0, 0x7e, 0x71, 0x35, 0x4b, 0x18, 0x66, 0xf7, 0x81, 0xf7, 0xee, 0xbc, 0x39, 0xb8, 0x17, 0x09, + 0x95, 0x56, 0x9d, 0x5f, 0x3b, 0xc9, 0xfd, 0xad, 0xf1, 0x8c, 0x9a, 0xca, 0x59, 0xdb, 0x39, 0x66, + 0xf5, 0x82, 0xdc, 0x84, 0xc9, 0x3d, 0xcf, 0xe9, 0x77, 0x69, 0x50, 0x2b, 0x8b, 0x4d, 0x61, 0x36, + 0x6b, 0xad, 0xde, 0x15, 0x24, 0x8d, 0x33, 0x8a, 0xfd, 0xa4, 0x7c, 0x0e, 0x50, 0xb7, 0x25, 0x36, + 0x4c, 0x38, 0x76, 0xd7, 0x66, 0x81, 0xd0, 0x96, 0xd5, 0xf9, 0x9b, 0x23, 0xbf, 0x96, 0x5c, 0xa2, + 0x6b, 0x82, 0x99, 0x5c, 0x35, 0xf2, 0x37, 0x2a, 0x01, 0xc4, 0x82, 0x52, 0x60, 0x99, 0x8e, 0xd4, + 0xa6, 0xd5, 0xf9, 0x8f, 0x8e, 0xbe, 0x6c, 0x38, 0x97, 0xc6, 0xb4, 0x7a, 0xa7, 0x92, 0x78, 0x44, + 0xc9, 0x9b, 0xfc, 0x3c, 0xcc, 0x24, 0xbe, 0x66, 0x50, 0xab, 0x8a, 0xd1, 0x79, 0x36, 0x6b, 0x74, + 0x42, 0xaa, 0xc6, 0x25, 0xc5, 0x6c, 0x26, 0x31, 0x43, 0x02, 0x4c, 0x31, 0x23, 0xb7, 0xa0, 0x1c, + 0xd8, 0x2d, 0x6a, 0x99, 0x7e, 0x50, 0x9b, 0x3a, 0x0a, 0xe3, 0xb3, 0x8a, 0x71, 0xb9, 0xa9, 0x9a, + 0x61, 0xc8, 0x80, 0xcc, 0x01, 0xf4, 0x4c, 0x9f, 0xd9, 0xd2, 0x3a, 0x99, 0x16, 0x3b, 0xe5, 0xcc, + 0xe1, 0x41, 0x1d, 0x36, 0x42, 0x28, 0xc6, 0x28, 0x38, 0x3d, 0x6f, 0xbb, 0xea, 0xf6, 0xfa, 0x2c, + 0xa8, 0xcd, 0x5c, 0x2b, 0x5c, 0xaf, 0x48, 0xfa, 0x66, 0x08, 0xc5, 0x18, 0x05, 0xf9, 0x6a, 0x0e, + 0x9e, 0x89, 0x1e, 0x07, 0x17, 0xd9, 0x99, 0x13, 0x5f, 0x64, 0xf5, 0xc3, 0x83, 0xfa, 0x33, 0xcd, + 0xe1, 0x22, 0xf1, 0x51, 0xfd, 0x31, 0xee, 0xc1, 0xf4, 0x42, 0x9f, 0xed, 0x7a, 0xbe, 0xfd, 0xb6, + 0xb0, 0xb4, 0xc8, 0x32, 0x94, 0x98, 0xd8, 0x31, 0xa5, 0x11, 0xfb, 0x5c, 0xd6, 0x50, 0x4b, 0xeb, + 0xe5, 0x16, 0xdd, 0xd7, 0x1b, 0x4d, 0xa3, 0xc2, 0x27, 0x85, 0xdc, 0x41, 0x65, 0x73, 0xe3, 0xf7, + 0x72, 0x50, 0x69, 0x98, 0x81, 0x6d, 0x71, 0xf6, 0x64, 0x11, 0x8a, 0xfd, 0x80, 0xfa, 0xc7, 0x63, + 0x2a, 0xb4, 0xf4, 0x56, 0x40, 0x7d, 0x14, 0x8d, 0xc9, 0x1d, 0x28, 0xf7, 0xcc, 0x20, 0xb8, 0xef, + 0xf9, 0x2d, 0xb5, 0xd3, 0x1c, 0x91, 0x91, 0x34, 0x85, 0x54, 0x53, 0x0c, 0x99, 0x18, 0x55, 0xa8, + 0x34, 0x1c, 0xd3, 0xea, 0xec, 0x7a, 0x0e, 0x35, 0x7e, 0x90, 0x83, 0xf3, 0x8d, 0xfe, 0xce, 0x0e, + 0xf5, 0xd5, 0xce, 0x2f, 0xf7, 0x54, 0x42, 0xa1, 0xe4, 0xd3, 0x96, 0x1d, 0xa8, 0xbe, 0x2f, 0x8d, + 0xfc, 0xe9, 0x90, 0x73, 0x51, 0x5b, 0xb8, 0x18, 0x2f, 0x01, 0x40, 0xc9, 0x9d, 0xf4, 0xa1, 0xf2, + 0x16, 0x65, 0x01, 0xf3, 0xa9, 0xd9, 0x55, 0x6f, 0xf7, 0xea, 0xc8, 0xa2, 0x5e, 0xa3, 0xac, 0x29, + 0x38, 0xc5, 0x2d, 0x86, 0x10, 0x88, 0x91, 0x24, 0xe3, 0xaf, 0x4a, 0x30, 0xb5, 0xe8, 0x75, 0xb7, + 0x6d, 0x97, 0xb6, 0x6e, 0xb6, 0xda, 0x94, 0xbc, 0x09, 0x45, 0xda, 0x6a, 0x53, 0xf5, 0xb6, 0xa3, + 0xef, 0xb3, 0x9c, 0x59, 0x64, 0x2d, 0xf0, 0x27, 0x14, 0x8c, 0xc9, 0x1a, 0xcc, 0xec, 0xf8, 0x5e, + 0x57, 0xaa, 0xae, 0xcd, 0xfd, 0x9e, 0xb2, 0x42, 0x1a, 0xff, 0x4b, 0xab, 0x83, 0xe5, 0x04, 0xf6, + 0xe1, 0x41, 0x1d, 0xa2, 0x27, 0x4c, 0xb5, 0x25, 0xaf, 0x43, 0x2d, 0x82, 0x84, 0x6b, 0x78, 0x91, + 0x9b, 0x6c, 0xc2, 0x54, 0x28, 0x35, 0xae, 0x1c, 0x1e, 0xd4, 0x6b, 0xcb, 0x43, 0x68, 0x70, 0x68, + 0x6b, 0xf2, 0x4e, 0x0e, 0xce, 0x46, 0x48, 0xa9, 0x57, 0x95, 0x85, 0x70, 0x42, 0x0a, 0x5b, 0xd8, + 0xb6, 0xcb, 0x29, 0x11, 0x38, 0x20, 0x94, 0x2c, 0xc3, 0x14, 0xf3, 0x62, 0xe3, 0x55, 0x12, 0xe3, + 0x65, 0x68, 0x67, 0x6c, 0xd3, 0x1b, 0x3a, 0x5a, 0x89, 0x76, 0x04, 0xe1, 0x92, 0x7e, 0x4e, 0x8d, + 0xd4, 0x84, 0x18, 0xa9, 0xd9, 0xc3, 0x83, 0xfa, 0xa5, 0xcd, 0x4c, 0x0a, 0x1c, 0xd2, 0x92, 0x7c, + 0x36, 0x07, 0x33, 0x1a, 0xa5, 0xc6, 0x68, 0xf2, 0x24, 0xc7, 0x88, 0xf0, 0x19, 0xb1, 0x99, 0x10, + 0x80, 0x29, 0x81, 0xc6, 0x0f, 0x8b, 0x50, 0x09, 0x35, 0x1b, 0x79, 0x2f, 0x94, 0x84, 0x9b, 0xa5, + 0x0c, 0xd6, 0x70, 0xcb, 0x12, 0xde, 0x18, 0x4a, 0x1c, 0x79, 0x0e, 0x26, 0x2d, 0xaf, 0xdb, 0x35, + 0xdd, 0x96, 0x70, 0x9d, 0x2b, 0x8d, 0x2a, 0xdf, 0xa9, 0x17, 0x25, 0x08, 0x35, 0x8e, 0x5c, 0x81, + 0xa2, 0xe9, 0xb7, 0xa5, 0x17, 0x5b, 0x91, 0xfa, 0x68, 0xc1, 0x6f, 0x07, 0x28, 0xa0, 0xe4, 0xc3, + 0x50, 0xa0, 0xee, 0x5e, 0xad, 0x38, 0xdc, 0x14, 0xb8, 0xe9, 0xee, 0xdd, 0x35, 0xfd, 0x46, 0x55, + 0xf5, 0xa1, 0x70, 0xd3, 0xdd, 0x43, 0xde, 0x86, 0xac, 0xc1, 0x24, 0x75, 0xf7, 0xf8, 0xb7, 0x57, + 0xee, 0xe5, 0x7b, 0x86, 0x34, 0xe7, 0x24, 0xca, 0x2a, 0x0e, 0x0d, 0x0a, 0x05, 0x46, 0xcd, 0x82, + 0x7c, 0x1c, 0xa6, 0xa4, 0x6d, 0xb1, 0xce, 0xbf, 0x49, 0x50, 0x9b, 0x10, 0x2c, 0xeb, 0xc3, 0x8d, + 0x13, 0x41, 0x17, 0xb9, 0xf3, 0x31, 0x60, 0x80, 0x09, 0x56, 0xe4, 0xe3, 0x50, 0xd1, 0x91, 0x1a, + 0xfd, 0x65, 0x33, 0x3d, 0x61, 0x54, 0x44, 0x48, 0x3f, 0xd5, 0xb7, 0x7d, 0xda, 0xa5, 0x2e, 0x0b, + 0x1a, 0xe7, 0xb4, 0x6f, 0xa4, 0xb1, 0x01, 0x46, 0xdc, 0xc8, 0xf6, 0xa0, 0x4b, 0x2f, 0xfd, 0xd1, + 0xf7, 0x0e, 0xd1, 0xea, 0x23, 0xf8, 0xf3, 0x9f, 0x84, 0x33, 0xa1, 0xcf, 0xad, 0xdc, 0x36, 0xe9, + 0xa1, 0xbe, 0xc8, 0x9b, 0xaf, 0x26, 0x51, 0x0f, 0x0f, 0xea, 0xcf, 0x66, 0x38, 0x6e, 0x11, 0x01, + 0xa6, 0x99, 0x19, 0x7f, 0x59, 0x80, 0x41, 0xb3, 0x3b, 0x39, 0x68, 0xb9, 0x93, 0x1e, 0xb4, 0xf4, + 0x0b, 0x49, 0xf5, 0xf9, 0x92, 0x6a, 0x36, 0xfe, 0x4b, 0x65, 0x7d, 0x98, 0xc2, 0x49, 0x7f, 0x98, + 0x27, 0x65, 0xed, 0x18, 0x9f, 0x2f, 0xc2, 0xcc, 0x92, 0x49, 0xbb, 0x9e, 0xfb, 0x58, 0x27, 0x24, + 0xf7, 0x44, 0x38, 0x21, 0xd7, 0xa1, 0xec, 0xd3, 0x9e, 0x63, 0x5b, 0x66, 0x20, 0x3e, 0xbd, 0x8a, + 0xf4, 0xa0, 0x82, 0x61, 0x88, 0x1d, 0xe2, 0x7c, 0x16, 0x9e, 0x48, 0xe7, 0xb3, 0xf8, 0xa3, 0x77, + 0x3e, 0x8d, 0xcf, 0xe6, 0x41, 0x18, 0x2a, 0xe4, 0x1a, 0x14, 0xf9, 0x26, 0x9c, 0x0e, 0x79, 0x88, + 0x89, 0x23, 0x30, 0x64, 0x16, 0xf2, 0xcc, 0x53, 0x2b, 0x0f, 0x14, 0x3e, 0xbf, 0xe9, 0x61, 0x9e, + 0x79, 0xe4, 0x6d, 0x00, 0xcb, 0x73, 0x5b, 0xb6, 0x0e, 0x80, 0x8e, 0xf7, 0x62, 0xcb, 0x9e, 0x7f, + 0xdf, 0xf4, 0x5b, 0x8b, 0x21, 0x47, 0xe9, 0x7e, 0x44, 0xcf, 0x18, 0x93, 0x46, 0x5e, 0x86, 0x09, + 0xcf, 0x5d, 0xee, 0x3b, 0x8e, 0x18, 0xd0, 0x4a, 0xe3, 0x7f, 0x73, 0x9f, 0xf0, 0x8e, 0x80, 0x3c, + 0x3c, 0xa8, 0x5f, 0x96, 0xf6, 0x2d, 0x7f, 0xba, 0xe7, 0xdb, 0xcc, 0x76, 0xdb, 0x4d, 0xe6, 0x9b, + 0x8c, 0xb6, 0xf7, 0x51, 0x35, 0x33, 0x4c, 0xa8, 0x2e, 0xdb, 0x0f, 0x68, 0xeb, 0x9e, 0xed, 0xb6, + 0xbc, 0xfb, 0x04, 0x61, 0xc2, 0xa1, 0x6e, 0x9b, 0xed, 0xaa, 0xc9, 0x3f, 0x17, 0x5b, 0x6a, 0x61, + 0xd8, 0x3c, 0xea, 0x7e, 0x97, 0x32, 0x93, 0x2f, 0xbe, 0xa5, 0xbe, 0x0a, 0xec, 0x4a, 0x9f, 0x54, + 0x70, 0x40, 0xc5, 0xc9, 0xd8, 0x87, 0x73, 0x03, 0x2f, 0x45, 0x5a, 0x50, 0x64, 0x66, 0x5b, 0x6b, + 0xcb, 0xe5, 0x91, 0x87, 0x6b, 0xd3, 0x6c, 0xc7, 0x86, 0x4a, 0xec, 0xd8, 0x9b, 0x26, 0xdf, 0xb1, + 0x39, 0x77, 0xe3, 0x3f, 0x73, 0x50, 0x5e, 0xee, 0xbb, 0x96, 0xf0, 0x74, 0x1e, 0x1f, 0xd8, 0xd2, + 0xdb, 0x7f, 0x3e, 0x73, 0xfb, 0xef, 0xc3, 0x44, 0xe7, 0x7e, 0x68, 0x1e, 0x54, 0xe7, 0xd7, 0x47, + 0xff, 0xc6, 0xaa, 0x4b, 0x73, 0xb7, 0x04, 0x3f, 0x19, 0x6c, 0x9f, 0x51, 0x1d, 0x9a, 0xb8, 0x75, + 0x4f, 0x08, 0x55, 0xc2, 0x66, 0x3f, 0x0c, 0xd5, 0x18, 0xd9, 0xb1, 0xa2, 0x7b, 0x7f, 0x5a, 0x84, + 0x89, 0x95, 0x66, 0x73, 0x61, 0x63, 0x95, 0x7c, 0x10, 0xaa, 0x2a, 0x0e, 0x7b, 0x3b, 0x1a, 0x83, + 0x30, 0x0c, 0xdf, 0x8c, 0x50, 0x18, 0xa7, 0xe3, 0xc6, 0x95, 0x4f, 0x4d, 0xa7, 0xab, 0xa6, 0x7e, + 0x68, 0x5c, 0x21, 0x07, 0xa2, 0xc4, 0x11, 0x13, 0x66, 0xb8, 0xbf, 0xc6, 0x87, 0x50, 0xfa, 0x62, + 0x6a, 0x11, 0x1c, 0xd1, 0x5b, 0x13, 0x26, 0xdf, 0x56, 0x82, 0x01, 0xa6, 0x18, 0x92, 0x97, 0xa0, + 0x6c, 0xf6, 0xd9, 0xae, 0x30, 0x87, 0xe5, 0x4c, 0xbf, 0x22, 0xc2, 0xd4, 0x0a, 0xf6, 0xf0, 0xa0, + 0x3e, 0x75, 0x0b, 0x1b, 0x1f, 0xd4, 0xcf, 0x18, 0x52, 0xf3, 0xce, 0x69, 0xff, 0x4f, 0x75, 0xae, + 0x74, 0xec, 0xce, 0x6d, 0x24, 0x18, 0x60, 0x8a, 0x21, 0x79, 0x03, 0xa6, 0x3a, 0x74, 0x9f, 0x99, + 0xdb, 0x4a, 0xc0, 0xc4, 0x71, 0x04, 0x9c, 0xe5, 0x06, 0xd9, 0xad, 0x58, 0x73, 0x4c, 0x30, 0x23, + 0x01, 0x5c, 0xe8, 0x50, 0x7f, 0x9b, 0xfa, 0x9e, 0xf2, 0x25, 0x95, 0x90, 0xc9, 0xe3, 0x08, 0xa9, + 0x1d, 0x1e, 0xd4, 0x2f, 0xdc, 0xca, 0x60, 0x83, 0x99, 0xcc, 0x8d, 0x1f, 0xe6, 0xe0, 0xcc, 0x8a, + 0x4c, 0x84, 0x79, 0xbe, 0xdc, 0x52, 0xc9, 0x65, 0x28, 0xf8, 0xbd, 0xbe, 0x98, 0x39, 0x05, 0x19, + 0xf5, 0xc4, 0x8d, 0x2d, 0xe4, 0x30, 0xf2, 0x3a, 0x94, 0x5b, 0x4a, 0x03, 0x28, 0x57, 0xf6, 0xb8, + 0x7a, 0x43, 0x6c, 0x69, 0xfa, 0x09, 0x43, 0x6e, 0xdc, 0x6e, 0xef, 0x06, 0xed, 0xa6, 0xfd, 0x36, + 0x55, 0xde, 0x9d, 0xb0, 0xdb, 0xd7, 0x25, 0x08, 0x35, 0x8e, 0xef, 0x91, 0x1d, 0xba, 0x2f, 0x7d, + 0x9b, 0x62, 0xb4, 0x47, 0xde, 0x52, 0x30, 0x0c, 0xb1, 0xa4, 0xae, 0x17, 0x0b, 0x9f, 0x05, 0x45, + 0xe9, 0x97, 0xdf, 0xe5, 0x00, 0xb5, 0x6e, 0x8c, 0x2f, 0xe5, 0xe1, 0xd2, 0x0a, 0x65, 0xd2, 0x44, + 0x58, 0xa2, 0x3d, 0xc7, 0xdb, 0xe7, 0x76, 0x1a, 0xd2, 0x4f, 0x91, 0x57, 0x00, 0xec, 0x60, 0xbb, + 0xb9, 0x67, 0x89, 0x69, 0x28, 0x97, 0xd0, 0x35, 0xb5, 0x22, 0x60, 0xb5, 0xd9, 0x50, 0x98, 0x87, + 0x89, 0x27, 0x8c, 0xb5, 0x89, 0x7c, 0x95, 0xfc, 0x23, 0x7c, 0x95, 0x26, 0x40, 0x2f, 0xb2, 0xf6, + 0x0a, 0x82, 0xf2, 0xff, 0x6b, 0x31, 0xc7, 0x31, 0xf4, 0x62, 0x6c, 0xc6, 0xb0, 0xbf, 0x8c, 0x3f, + 0x2b, 0xc0, 0xec, 0x0a, 0x65, 0x61, 0x38, 0x41, 0x29, 0x8b, 0x66, 0x8f, 0x5a, 0x7c, 0x54, 0xde, + 0xc9, 0xc1, 0x84, 0x63, 0x6e, 0x53, 0x87, 0x2b, 0x73, 0xce, 0xfd, 0xcd, 0x91, 0xf5, 0xe2, 0x70, + 0x29, 0x73, 0x6b, 0x42, 0x42, 0x4a, 0x53, 0x4a, 0x20, 0x2a, 0xf1, 0x5c, 0xc7, 0x59, 0x4e, 0x3f, + 0x60, 0xd4, 0xdf, 0xf0, 0x7c, 0xa6, 0x8c, 0xa5, 0x50, 0xc7, 0x2d, 0x46, 0x28, 0x8c, 0xd3, 0x91, + 0x79, 0x00, 0xcb, 0xb1, 0xa9, 0xcb, 0x44, 0x2b, 0x39, 0xcd, 0x88, 0x1e, 0xef, 0xc5, 0x10, 0x83, + 0x31, 0x2a, 0x2e, 0xaa, 0xeb, 0xb9, 0x36, 0xf3, 0xa4, 0xa8, 0x62, 0x52, 0xd4, 0x7a, 0x84, 0xc2, + 0x38, 0x9d, 0x68, 0x46, 0x99, 0x6f, 0x5b, 0x81, 0x68, 0x56, 0x4a, 0x35, 0x8b, 0x50, 0x18, 0xa7, + 0xe3, 0x5b, 0x40, 0xec, 0xfd, 0x8f, 0xb5, 0x05, 0xfc, 0x79, 0x19, 0xae, 0x26, 0x86, 0x95, 0x99, + 0x8c, 0xee, 0xf4, 0x9d, 0x26, 0x65, 0xfa, 0x03, 0x8e, 0xb8, 0x35, 0x7c, 0x31, 0xfa, 0xee, 0x32, + 0x1b, 0x6d, 0x9d, 0xcc, 0x77, 0x1f, 0xe8, 0xe0, 0x91, 0xbe, 0xfd, 0x0d, 0xa8, 0xb8, 0x26, 0x0b, + 0xc4, 0x42, 0x52, 0x6b, 0x26, 0x74, 0xac, 0x6e, 0x6b, 0x04, 0x46, 0x34, 0x64, 0x03, 0x2e, 0xa8, + 0x21, 0xbe, 0xf9, 0xa0, 0xe7, 0xf9, 0x8c, 0xfa, 0xb2, 0xad, 0xda, 0x5d, 0x54, 0xdb, 0x0b, 0xeb, + 0x19, 0x34, 0x98, 0xd9, 0x92, 0xac, 0xc3, 0x79, 0x4b, 0x66, 0xe8, 0xa8, 0xe3, 0x99, 0x2d, 0xcd, + 0x50, 0x46, 0x6f, 0x42, 0xbb, 0x7f, 0x71, 0x90, 0x04, 0xb3, 0xda, 0xa5, 0x67, 0xf3, 0xc4, 0x48, + 0xb3, 0x79, 0x72, 0x94, 0xd9, 0x5c, 0x1e, 0x6d, 0x36, 0x57, 0x8e, 0x36, 0x9b, 0xf9, 0xc8, 0xf3, + 0x79, 0x44, 0x7d, 0xbe, 0x5b, 0xcb, 0x0d, 0x27, 0x96, 0x00, 0x0e, 0x47, 0xbe, 0x99, 0x41, 0x83, + 0x99, 0x2d, 0xc9, 0x36, 0xcc, 0x4a, 0xf8, 0x4d, 0xd7, 0xf2, 0xf7, 0x7b, 0x7c, 0xe7, 0x88, 0xf1, + 0xad, 0x26, 0xc2, 0x67, 0xb3, 0xcd, 0xa1, 0x94, 0xf8, 0x08, 0x2e, 0xe4, 0x67, 0x60, 0x5a, 0x7e, + 0xa5, 0x75, 0xb3, 0x27, 0xd8, 0xca, 0x74, 0xf0, 0x45, 0xc5, 0x76, 0x7a, 0x31, 0x8e, 0xc4, 0x24, + 0x2d, 0x59, 0x80, 0x33, 0xbd, 0x3d, 0x8b, 0xff, 0x5c, 0xdd, 0xb9, 0x4d, 0x69, 0x8b, 0xb6, 0x44, + 0x2a, 0xa2, 0xd2, 0x78, 0x5a, 0x7b, 0xf1, 0x1b, 0x49, 0x34, 0xa6, 0xe9, 0xc9, 0x4b, 0x30, 0x15, + 0x30, 0xd3, 0x67, 0x2a, 0x66, 0x55, 0x9b, 0x91, 0xe9, 0x72, 0x1d, 0xd2, 0x69, 0xc6, 0x70, 0x98, + 0xa0, 0x1c, 0x47, 0x7b, 0x3c, 0x94, 0x9b, 0xa1, 0x08, 0x5c, 0xa7, 0xd4, 0xfe, 0xe7, 0xd2, 0x6a, + 0xff, 0x8d, 0x71, 0x96, 0x7f, 0x86, 0x84, 0x23, 0x2d, 0xfb, 0xd7, 0x80, 0xf8, 0x2a, 0xcc, 0x2e, + 0x9d, 0xbb, 0x98, 0xe6, 0x0f, 0x8b, 0x12, 0x70, 0x80, 0x02, 0x33, 0x5a, 0x91, 0x26, 0x5c, 0x0c, + 0xa8, 0xcb, 0x6c, 0x97, 0x3a, 0x49, 0x76, 0x72, 0x4b, 0x78, 0x56, 0xb1, 0xbb, 0xd8, 0xcc, 0x22, + 0xc2, 0xec, 0xb6, 0xe3, 0x0c, 0xfe, 0x3f, 0x55, 0xc4, 0xbe, 0x2b, 0x87, 0xe6, 0xc4, 0xd4, 0xf6, + 0x3b, 0x69, 0xb5, 0xfd, 0xe6, 0xf8, 0xdf, 0x6d, 0x34, 0x95, 0x3d, 0x0f, 0x20, 0xbe, 0x42, 0x5c, + 0x67, 0x87, 0x9a, 0x0a, 0x43, 0x0c, 0xc6, 0xa8, 0xf8, 0x2a, 0xd4, 0xe3, 0x1c, 0x57, 0xd7, 0xe1, + 0x2a, 0x6c, 0xc6, 0x91, 0x98, 0xa4, 0x1d, 0xaa, 0xf2, 0x4b, 0x23, 0xab, 0xfc, 0xd7, 0x80, 0x24, + 0x42, 0x0b, 0x92, 0xdf, 0x44, 0xb2, 0x26, 0x66, 0x75, 0x80, 0x02, 0x33, 0x5a, 0x0d, 0x99, 0xca, + 0x93, 0x27, 0x3b, 0x95, 0xcb, 0xa3, 0x4f, 0x65, 0xf2, 0x26, 0x5c, 0x16, 0xa2, 0xd4, 0xf8, 0x24, + 0x19, 0x4b, 0xe5, 0xff, 0x1e, 0xc5, 0xf8, 0x32, 0x0e, 0x23, 0xc4, 0xe1, 0x3c, 0xf8, 0xf7, 0xb1, + 0x7c, 0xda, 0xe2, 0xc2, 0x4d, 0x67, 0xf8, 0xc6, 0xb0, 0x98, 0x41, 0x83, 0x99, 0x2d, 0xf9, 0x14, + 0x63, 0x7c, 0x1a, 0x9a, 0xdb, 0x0e, 0x6d, 0xa9, 0x9a, 0xa0, 0x70, 0x8a, 0x6d, 0xae, 0x35, 0x15, + 0x06, 0x63, 0x54, 0x59, 0xba, 0x7a, 0xea, 0x98, 0xba, 0x7a, 0x45, 0xc4, 0xe1, 0x76, 0x12, 0x5b, + 0x82, 0x52, 0xf8, 0x61, 0x95, 0xd7, 0x62, 0x9a, 0x00, 0x07, 0xdb, 0x88, 0xad, 0xd2, 0xf2, 0xed, + 0x1e, 0x0b, 0x92, 0xbc, 0x66, 0x52, 0x5b, 0x65, 0x06, 0x0d, 0x66, 0xb6, 0xe4, 0x46, 0xca, 0x2e, + 0x35, 0x1d, 0xb6, 0x9b, 0x64, 0x78, 0x26, 0x69, 0xa4, 0xbc, 0x3a, 0x48, 0x82, 0x59, 0xed, 0xc6, + 0x51, 0x6f, 0xbf, 0x91, 0x87, 0xcb, 0x2b, 0x94, 0x85, 0x99, 0xec, 0x9f, 0xf8, 0x5a, 0xee, 0x9e, + 0xf1, 0x9d, 0x3c, 0x9c, 0x5f, 0xa1, 0xaa, 0x14, 0x6b, 0xc3, 0x6b, 0x69, 0x65, 0xff, 0x3f, 0x73, + 0x38, 0xf8, 0x6c, 0x8d, 0x8a, 0x19, 0x9a, 0xcc, 0xf3, 0xe5, 0x5e, 0x97, 0x32, 0xa9, 0x9b, 0x83, + 0x24, 0x98, 0xd5, 0xce, 0xf8, 0xf7, 0x3c, 0x4c, 0xae, 0xf8, 0x5e, 0xbf, 0xd7, 0xd8, 0x27, 0x6d, + 0x98, 0xb8, 0x2f, 0x62, 0x9e, 0x2a, 0x04, 0x39, 0x7a, 0x11, 0x9b, 0x0c, 0x9d, 0x46, 0xdb, 0x9c, + 0x7c, 0x46, 0xc5, 0x9e, 0x0f, 0x7c, 0x87, 0xee, 0x53, 0x59, 0xc2, 0x50, 0x8e, 0x06, 0xfe, 0x16, + 0x07, 0xa2, 0xc4, 0x91, 0x2e, 0x9c, 0x31, 0x1d, 0xc7, 0xbb, 0x4f, 0x5b, 0x6b, 0x26, 0xa3, 0x2e, + 0x0d, 0x74, 0x20, 0xf9, 0xb8, 0x81, 0x14, 0x91, 0x8d, 0x59, 0x48, 0xb2, 0xc2, 0x34, 0x6f, 0xf2, + 0x16, 0x4c, 0x06, 0xcc, 0xf3, 0xf5, 0x06, 0x5a, 0x9d, 0x5f, 0x1c, 0xf9, 0xed, 0x37, 0x1a, 0x1f, + 0x6b, 0x4a, 0x56, 0x32, 0x36, 0xa3, 0x1e, 0x50, 0x0b, 0x30, 0xbe, 0x92, 0x03, 0x78, 0x75, 0x73, + 0x73, 0x43, 0x85, 0x91, 0x5a, 0x50, 0x34, 0xfb, 0x61, 0x7c, 0x79, 0xf4, 0xc0, 0x6f, 0xa2, 0x8a, + 0x45, 0xc5, 0x6a, 0xfb, 0x6c, 0x17, 0x05, 0x77, 0xf2, 0x3e, 0x98, 0x54, 0x46, 0x8f, 0x1a, 0xf6, + 0x30, 0x21, 0xa4, 0x0c, 0x23, 0xd4, 0x78, 0xe3, 0xfb, 0x79, 0xb8, 0xb4, 0xea, 0x32, 0xea, 0x37, + 0x19, 0xed, 0x25, 0x0a, 0x42, 0xc8, 0x2f, 0x0c, 0xd4, 0x78, 0xff, 0xbf, 0xa3, 0x7d, 0x0e, 0x59, + 0x22, 0xbc, 0x4e, 0x99, 0x19, 0x6d, 0x37, 0x11, 0x2c, 0x56, 0xd8, 0xdd, 0x87, 0x62, 0xd0, 0xa3, + 0x96, 0x8a, 0x9a, 0x35, 0x47, 0x1e, 0x8d, 0xec, 0x17, 0xe0, 0xda, 0x23, 0x0a, 0x74, 0x0b, 0x5d, + 0x22, 0xc4, 0x91, 0x4f, 0xc3, 0x44, 0xc0, 0x4c, 0xd6, 0xd7, 0xb3, 0x6c, 0xeb, 0xa4, 0x05, 0x0b, + 0xe6, 0xd1, 0x92, 0x90, 0xcf, 0xa8, 0x84, 0x1a, 0xdf, 0xcf, 0xc1, 0x6c, 0x76, 0xc3, 0x35, 0x3b, + 0x60, 0xe4, 0xe7, 0x06, 0x86, 0xfd, 0x88, 0xab, 0x80, 0xb7, 0x16, 0x83, 0x1e, 0x56, 0x84, 0x69, + 0x48, 0x6c, 0xc8, 0x19, 0x94, 0x6c, 0x46, 0xbb, 0xda, 0xfc, 0xbd, 0x73, 0xc2, 0xaf, 0x1e, 0xd3, + 0xac, 0x5c, 0x0a, 0x4a, 0x61, 0xc6, 0xe7, 0xf3, 0xc3, 0x5e, 0x99, 0x7f, 0x16, 0xe2, 0x24, 0x8b, + 0x8e, 0x6e, 0x8d, 0x57, 0x74, 0x94, 0xec, 0xd0, 0x60, 0xed, 0xd1, 0x2f, 0x0d, 0xd6, 0x1e, 0xdd, + 0x19, 0xbf, 0xf6, 0x28, 0x35, 0x0c, 0x43, 0x4b, 0x90, 0x7e, 0xb5, 0x00, 0x57, 0x1e, 0x35, 0x6d, + 0xb8, 0x6a, 0x56, 0xb3, 0x73, 0x5c, 0xd5, 0xfc, 0xe8, 0x79, 0x48, 0xe6, 0xa1, 0xd4, 0xdb, 0x35, + 0x03, 0xbd, 0x27, 0x6a, 0x7b, 0xaa, 0xb4, 0xc1, 0x81, 0x0f, 0x0f, 0xea, 0x55, 0xb9, 0x97, 0x8a, + 0x47, 0x94, 0xa4, 0x5c, 0xb3, 0x74, 0x69, 0x10, 0x44, 0x2e, 0x4b, 0xa8, 0x59, 0xd6, 0x25, 0x18, + 0x35, 0x9e, 0x30, 0x98, 0x90, 0x61, 0x00, 0xa5, 0x64, 0x47, 0xcf, 0x24, 0x67, 0xd4, 0xa9, 0x45, + 0x2f, 0xa5, 0x22, 0x4a, 0x4a, 0x16, 0x99, 0x83, 0x22, 0x8b, 0xaa, 0x86, 0xb4, 0xe7, 0x50, 0xcc, + 0x30, 0x0f, 0x04, 0x9d, 0xf1, 0xf7, 0x65, 0xb8, 0x94, 0xfd, 0x0d, 0xf9, 0xbb, 0xee, 0x51, 0x3f, + 0xb0, 0x3d, 0x57, 0x99, 0x1c, 0x51, 0x8d, 0xab, 0x04, 0xa3, 0xc6, 0xff, 0x58, 0x67, 0xa9, 0xff, + 0x20, 0xc7, 0x3d, 0x1b, 0x19, 0x7b, 0x7b, 0x37, 0x32, 0xd5, 0xcf, 0x4a, 0x0f, 0x69, 0x88, 0x40, + 0x1c, 0xde, 0x17, 0xf2, 0xfb, 0x39, 0xa8, 0x75, 0x53, 0xae, 0xd3, 0x29, 0x56, 0x99, 0x8b, 0x52, + 0xba, 0xf5, 0x21, 0xf2, 0x70, 0x68, 0x4f, 0xc8, 0x2f, 0x43, 0xb5, 0xc7, 0xe7, 0x45, 0xc0, 0xa8, + 0x6b, 0xe9, 0x42, 0xf3, 0xd1, 0x67, 0xff, 0x46, 0xc4, 0x4b, 0xe7, 0xaf, 0x1b, 0x67, 0x0e, 0x0f, + 0xea, 0xd5, 0x18, 0x02, 0xe3, 0x12, 0x9f, 0xf0, 0xb2, 0xf2, 0xeb, 0x50, 0x0e, 0x28, 0x63, 0xb6, + 0xdb, 0x0e, 0x84, 0x43, 0x5e, 0x91, 0x6b, 0xa5, 0xa9, 0x60, 0x18, 0x62, 0xc9, 0xff, 0x85, 0x8a, + 0x08, 0xe5, 0x2d, 0xf8, 0xed, 0xa0, 0x56, 0x11, 0x59, 0x69, 0xa1, 0x57, 0x9b, 0x1a, 0x88, 0x11, + 0x9e, 0xbc, 0x08, 0x53, 0xdb, 0x62, 0xf9, 0xaa, 0xe3, 0x25, 0xd2, 0x6d, 0x16, 0xf9, 0xc5, 0x46, + 0x0c, 0x8e, 0x09, 0x2a, 0xee, 0x22, 0xd3, 0x30, 0xde, 0x99, 0x76, 0x91, 0xa3, 0x48, 0x28, 0xc6, + 0xa8, 0xc8, 0xb3, 0x50, 0x60, 0x4e, 0x20, 0xdc, 0xe2, 0x72, 0x64, 0xb5, 0x6f, 0xae, 0x35, 0x91, + 0xc3, 0x8d, 0xff, 0xca, 0xc1, 0x99, 0x54, 0x45, 0x2a, 0x6f, 0xd2, 0xf7, 0x1d, 0xa5, 0x46, 0xc2, + 0x26, 0x5b, 0xb8, 0x86, 0x1c, 0x4e, 0xde, 0x54, 0x56, 0x61, 0x7e, 0xcc, 0x93, 0x74, 0xb7, 0x4d, + 0x16, 0x70, 0x33, 0x70, 0xc0, 0x20, 0x14, 0xe1, 0xd3, 0xa8, 0x3f, 0x4a, 0x77, 0xc7, 0xc2, 0xa7, + 0x11, 0x0e, 0x13, 0x94, 0xa9, 0x18, 0x42, 0xf1, 0x28, 0x31, 0x04, 0xe3, 0x6f, 0x0b, 0x50, 0x7d, + 0xcd, 0xdb, 0xfe, 0x31, 0xa9, 0x30, 0xca, 0xd6, 0xc8, 0xf9, 0x1f, 0xa1, 0x46, 0xde, 0x82, 0xa7, + 0x19, 0x73, 0x9a, 0xd4, 0xf2, 0xdc, 0x56, 0xb0, 0xb0, 0xc3, 0xa8, 0xbf, 0x6c, 0xbb, 0x76, 0xb0, + 0x4b, 0x5b, 0x2a, 0x18, 0xfb, 0xcc, 0xe1, 0x41, 0xfd, 0xe9, 0xcd, 0xcd, 0xb5, 0x2c, 0x12, 0x1c, + 0xd6, 0x56, 0xac, 0x10, 0xd3, 0xea, 0x78, 0x3b, 0x3b, 0xa2, 0x92, 0x54, 0xa5, 0xed, 0xe4, 0x0a, + 0x89, 0xc1, 0x31, 0x41, 0x65, 0x7c, 0x2d, 0x0f, 0x95, 0x5b, 0xe6, 0x4e, 0xc7, 0x6c, 0xda, 0x6e, + 0x87, 0x3c, 0x07, 0x93, 0xdb, 0xbe, 0xd7, 0xa1, 0xbe, 0x8c, 0x7b, 0xab, 0x4a, 0xd2, 0x86, 0x04, + 0xa1, 0xc6, 0x71, 0xaf, 0x8f, 0x79, 0x3d, 0xdb, 0x4a, 0xbb, 0xdb, 0x9b, 0x1c, 0x88, 0x12, 0x47, + 0xee, 0xc9, 0x75, 0x54, 0x18, 0xf3, 0x18, 0xd2, 0xe6, 0x5a, 0x53, 0x26, 0xe4, 0xf5, 0x0a, 0x24, + 0xcf, 0x27, 0x2c, 0x8f, 0xca, 0x50, 0x5b, 0xe1, 0x0d, 0x28, 0x06, 0x66, 0xe0, 0xa8, 0xad, 0x63, + 0x8c, 0x43, 0x56, 0x0b, 0xcd, 0x35, 0x75, 0xc8, 0x6a, 0xa1, 0xb9, 0x86, 0x82, 0xa9, 0xf1, 0xc3, + 0x3c, 0x54, 0xe5, 0xb8, 0x49, 0xcf, 0xef, 0x24, 0x47, 0xee, 0x65, 0x91, 0x8d, 0x09, 0xfa, 0x5d, + 0xea, 0x0b, 0x87, 0x5e, 0xad, 0xe7, 0x78, 0x74, 0x2d, 0x42, 0x86, 0x19, 0x99, 0x08, 0xa4, 0x87, + 0xbe, 0x78, 0x8a, 0x43, 0x5f, 0x3a, 0xd2, 0xd0, 0x4f, 0x9c, 0xc6, 0xd0, 0xff, 0x51, 0x0e, 0x2a, + 0x6b, 0xf6, 0x0e, 0xb5, 0xf6, 0x2d, 0x47, 0xd4, 0xcc, 0xb7, 0xa8, 0x43, 0x19, 0x5d, 0xf1, 0x4d, + 0x8b, 0x6e, 0x50, 0xdf, 0x16, 0xc7, 0x65, 0xf9, 0xfa, 0x10, 0x1a, 0x48, 0xd5, 0xcc, 0x2f, 0x0d, + 0xa1, 0xc1, 0xa1, 0xad, 0xc9, 0x2a, 0x4c, 0xb5, 0x68, 0x60, 0xfb, 0xb4, 0xb5, 0x11, 0xb3, 0xa3, + 0x9f, 0xd3, 0x5a, 0x75, 0x29, 0x86, 0x7b, 0x78, 0x50, 0x9f, 0xde, 0xb0, 0x7b, 0xd4, 0xb1, 0x5d, + 0x2a, 0x0d, 0xea, 0x44, 0x53, 0xa3, 0x04, 0x85, 0x35, 0xaf, 0x6d, 0x7c, 0xbe, 0x00, 0xe1, 0x01, + 0x68, 0xf2, 0x85, 0x1c, 0x54, 0x4d, 0xd7, 0xf5, 0x98, 0x3a, 0x5c, 0x2c, 0x13, 0x4d, 0x38, 0xf6, + 0x39, 0xeb, 0xb9, 0x85, 0x88, 0xa9, 0xcc, 0x51, 0x84, 0x79, 0x93, 0x18, 0x06, 0xe3, 0xb2, 0x49, + 0x3f, 0x95, 0x36, 0x59, 0x1f, 0xbf, 0x17, 0x47, 0x48, 0x92, 0xcc, 0x7e, 0x14, 0xce, 0xa6, 0x3b, + 0x7b, 0x9c, 0x28, 0xeb, 0x38, 0x01, 0xda, 0xcf, 0x55, 0xa0, 0x7a, 0xdb, 0x64, 0xf6, 0x1e, 0x15, + 0xce, 0xe3, 0xe9, 0x78, 0x03, 0xbf, 0x93, 0x83, 0x4b, 0xc9, 0x04, 0xc6, 0x29, 0xba, 0x04, 0xe2, + 0xc0, 0x03, 0x66, 0x4a, 0xc3, 0x21, 0xbd, 0x10, 0xce, 0xc1, 0x40, 0x3e, 0xe4, 0xb4, 0x9d, 0x83, + 0xe6, 0x30, 0x81, 0x38, 0xbc, 0x2f, 0x3f, 0x2e, 0xce, 0xc1, 0x93, 0x7d, 0x20, 0x35, 0xe5, 0xba, + 0x4c, 0x3e, 0x31, 0xae, 0x4b, 0xf9, 0x89, 0x30, 0x15, 0x7b, 0x31, 0xd7, 0xa5, 0x32, 0x66, 0x04, + 0x57, 0xe5, 0xfc, 0x25, 0xb7, 0x61, 0x2e, 0x90, 0x28, 0xe1, 0xd5, 0x56, 0x3d, 0xb1, 0xa0, 0xb4, + 0x6d, 0x06, 0xb6, 0xa5, 0x0c, 0xe7, 0xc6, 0xe8, 0x01, 0x15, 0x7d, 0x52, 0x51, 0x46, 0xc7, 0xc4, + 0x23, 0x4a, 0xde, 0xd1, 0x89, 0xc8, 0xfc, 0x58, 0x27, 0x22, 0xc9, 0x22, 0x14, 0x5d, 0xae, 0x6c, + 0x0b, 0xc7, 0x3e, 0x03, 0x79, 0xfb, 0x16, 0xdd, 0x47, 0xd1, 0x98, 0x1b, 0x9f, 0xc0, 0x5f, 0x5f, + 0xd9, 0x50, 0x8f, 0x71, 0xa3, 0xde, 0x07, 0x93, 0x41, 0x5f, 0xc4, 0x99, 0xd5, 0x56, 0x1c, 0x85, + 0xbd, 0x25, 0x18, 0x35, 0x9e, 0x9b, 0x59, 0x9f, 0xea, 0xd3, 0xbe, 0x8e, 0x62, 0x85, 0x66, 0xd6, + 0xc7, 0x38, 0x10, 0x25, 0xee, 0xf4, 0xac, 0x24, 0xed, 0xef, 0x95, 0x4e, 0xc9, 0xdf, 0x33, 0x3e, + 0x93, 0x07, 0x88, 0x52, 0x13, 0xe4, 0x2b, 0x39, 0xb8, 0x18, 0xae, 0x32, 0x26, 0xcf, 0x3f, 0x2d, + 0x3a, 0xa6, 0xdd, 0x1d, 0xdb, 0x05, 0xcb, 0x5a, 0xe1, 0x42, 0xed, 0x6c, 0x64, 0x89, 0xc3, 0xec, + 0x5e, 0x10, 0x84, 0x32, 0xed, 0xf6, 0xd8, 0xfe, 0x92, 0xed, 0xab, 0x69, 0x97, 0x79, 0x80, 0xe8, + 0xa6, 0xa2, 0x91, 0x4d, 0xd5, 0x59, 0x17, 0xb1, 0x72, 0x34, 0x06, 0x43, 0x3e, 0xc6, 0x97, 0xf3, + 0x70, 0x3e, 0xa3, 0x77, 0xe4, 0x15, 0x38, 0xab, 0x72, 0x33, 0xd1, 0xe5, 0x1b, 0xb9, 0xe8, 0xf2, + 0x8d, 0x66, 0x0a, 0x87, 0x03, 0xd4, 0xe4, 0x4d, 0x00, 0xd3, 0xb2, 0x68, 0x10, 0xac, 0x7b, 0x2d, + 0x6d, 0xf4, 0xbd, 0xcc, 0xdd, 0xe1, 0x85, 0x10, 0xfa, 0xf0, 0xa0, 0xfe, 0x81, 0xac, 0x14, 0x61, + 0xea, 0xed, 0xa3, 0x06, 0x18, 0x63, 0x49, 0x3e, 0x09, 0x20, 0x4f, 0xa5, 0x85, 0x95, 0xbf, 0x8f, + 0xc9, 0x01, 0xcc, 0xe9, 0x13, 0x53, 0x73, 0x1f, 0xeb, 0x9b, 0x2e, 0xb3, 0xd9, 0xbe, 0x3c, 0x36, + 0x71, 0x37, 0xe4, 0x82, 0x31, 0x8e, 0xc6, 0x5f, 0xe7, 0xa1, 0xac, 0x8d, 0xd1, 0x77, 0x21, 0xcb, + 0xd3, 0x4e, 0x64, 0x79, 0x46, 0x3f, 0x29, 0xa9, 0xbb, 0x3c, 0x34, 0xaf, 0xe3, 0xa5, 0xf2, 0x3a, + 0x2b, 0xe3, 0x8b, 0x7a, 0x74, 0x26, 0xe7, 0xab, 0x79, 0x98, 0xd1, 0xa4, 0xea, 0xf4, 0xea, 0x87, + 0x60, 0xda, 0xa7, 0x66, 0xab, 0x61, 0x32, 0x6b, 0x57, 0x7c, 0xbe, 0x9c, 0xa8, 0xb4, 0x3e, 0x77, + 0x78, 0x50, 0x9f, 0xc6, 0x38, 0x02, 0x93, 0x74, 0xe4, 0x23, 0x70, 0x46, 0x46, 0xa6, 0xd6, 0xcd, + 0x07, 0xf2, 0x08, 0x89, 0x18, 0xb0, 0xa2, 0xcc, 0x69, 0x36, 0x92, 0x28, 0x4c, 0xd3, 0xf2, 0x69, + 0x2d, 0x41, 0x5b, 0x81, 0xd9, 0x96, 0x9d, 0x11, 0xa3, 0x30, 0x2d, 0xa7, 0x75, 0x23, 0x85, 0xc3, + 0x01, 0x6a, 0x62, 0x42, 0x95, 0xf7, 0x68, 0xd3, 0xee, 0x52, 0xaf, 0xaf, 0xef, 0x1b, 0x3a, 0x6e, + 0x02, 0x56, 0xec, 0xee, 0x18, 0xb1, 0xc1, 0x38, 0x4f, 0xe3, 0x1f, 0x72, 0x30, 0x15, 0x8d, 0xd7, + 0xa9, 0xe7, 0xba, 0x76, 0x92, 0xb9, 0xae, 0x85, 0xb1, 0xa7, 0xc3, 0x90, 0xec, 0xd6, 0xaf, 0x4d, + 0x46, 0xaf, 0x25, 0xf2, 0x59, 0xdb, 0x30, 0x6b, 0x67, 0xa6, 0x78, 0x62, 0xda, 0x26, 0xac, 0xc8, + 0x5c, 0x1d, 0x4a, 0x89, 0x8f, 0xe0, 0x42, 0xfa, 0x50, 0xde, 0xa3, 0x3e, 0xb3, 0x2d, 0xaa, 0xdf, + 0x6f, 0x65, 0x6c, 0xeb, 0x48, 0x16, 0x5e, 0x44, 0x63, 0x7a, 0x57, 0x09, 0xc0, 0x50, 0x14, 0xd9, + 0x86, 0x12, 0x6d, 0xb5, 0xa9, 0x3e, 0x05, 0x34, 0xe6, 0x89, 0xf9, 0x70, 0x3c, 0xf9, 0x53, 0x80, + 0x92, 0x35, 0x09, 0xa0, 0xe2, 0x68, 0xf7, 0x5d, 0xcd, 0xc3, 0xd1, 0x6d, 0x9d, 0x30, 0x10, 0x10, + 0x55, 0x44, 0x87, 0x20, 0x8c, 0xe4, 0x90, 0x4e, 0x78, 0x4d, 0x49, 0xe9, 0x84, 0x94, 0xc7, 0x23, + 0x2e, 0x2a, 0x09, 0xa0, 0x72, 0xdf, 0x64, 0xd4, 0xef, 0x9a, 0x7e, 0x47, 0x19, 0xfe, 0xa3, 0xbf, + 0xe1, 0x3d, 0xcd, 0x29, 0x7a, 0xc3, 0x10, 0x84, 0x91, 0x1c, 0xe2, 0x41, 0x85, 0x29, 0x4b, 0x56, + 0x1f, 0x6e, 0x1e, 0x5d, 0xa8, 0xb6, 0x89, 0x03, 0x19, 0x92, 0x0f, 0x1f, 0x31, 0x92, 0x41, 0xf6, + 0x12, 0xb7, 0x89, 0xc8, 0x3b, 0x64, 0x1a, 0x63, 0x5c, 0x65, 0xa4, 0x58, 0x45, 0xdb, 0x4d, 0xf6, + 0xad, 0x24, 0xc6, 0xc3, 0x42, 0xa4, 0x96, 0xdf, 0xed, 0xa4, 0xea, 0x8b, 0xc9, 0xa4, 0xea, 0xd5, + 0x74, 0x52, 0x35, 0x15, 0x05, 0x3a, 0x7e, 0x5a, 0xd5, 0x84, 0xaa, 0x63, 0x06, 0x6c, 0xab, 0xd7, + 0x32, 0x99, 0x8a, 0xc8, 0x57, 0xe7, 0xff, 0xcf, 0xd1, 0xb4, 0x26, 0xd7, 0xc3, 0x51, 0xb0, 0x67, + 0x2d, 0x62, 0x83, 0x71, 0x9e, 0xe4, 0x05, 0xa8, 0xee, 0x09, 0x4d, 0x20, 0x8f, 0x14, 0x95, 0xc4, + 0x36, 0x22, 0x34, 0xfb, 0xdd, 0x08, 0x8c, 0x71, 0x1a, 0xde, 0x44, 0x5a, 0x20, 0xd1, 0x0d, 0x0b, + 0xaa, 0x49, 0x33, 0x02, 0x63, 0x9c, 0x46, 0x64, 0x77, 0x6c, 0xb7, 0x23, 0x1b, 0x4c, 0x8a, 0x06, + 0x32, 0xbb, 0xa3, 0x81, 0x18, 0xe1, 0xc9, 0x75, 0x28, 0xf7, 0x5b, 0x3b, 0x92, 0xb6, 0x2c, 0x68, + 0x85, 0xdd, 0xb7, 0xb5, 0xb4, 0xac, 0x8e, 0x38, 0x69, 0xac, 0xf1, 0xbd, 0x1c, 0x90, 0xc1, 0x32, + 0x00, 0xb2, 0x0b, 0x13, 0xae, 0x88, 0xe6, 0x8c, 0x7d, 0xb1, 0x49, 0x2c, 0x28, 0x24, 0xd7, 0xb6, + 0x02, 0x28, 0xfe, 0xc4, 0x85, 0x32, 0x7d, 0xc0, 0xa8, 0xef, 0x9a, 0x8e, 0x32, 0x79, 0x4e, 0xe6, + 0x12, 0x15, 0x69, 0xe8, 0x2a, 0xce, 0x18, 0xca, 0x30, 0x7e, 0x90, 0x87, 0x6a, 0x8c, 0xee, 0x71, + 0x4e, 0x92, 0x28, 0x9c, 0x96, 0x41, 0x94, 0x2d, 0xdf, 0x51, 0xd3, 0x34, 0x56, 0x38, 0xad, 0x50, + 0xb8, 0x86, 0x71, 0x3a, 0x32, 0x0f, 0xd0, 0x35, 0x03, 0x46, 0x7d, 0xb1, 0x85, 0xa5, 0xca, 0x95, + 0xd7, 0x43, 0x0c, 0xc6, 0xa8, 0xc8, 0x35, 0x75, 0x0d, 0x4e, 0x31, 0x79, 0xe4, 0x74, 0xc8, 0x1d, + 0x37, 0xa5, 0x13, 0xb8, 0xe3, 0x86, 0xb4, 0xe1, 0xac, 0xee, 0xb5, 0xc6, 0x1e, 0xef, 0x40, 0xa2, + 0x74, 0x02, 0x52, 0x2c, 0x70, 0x80, 0xa9, 0xf1, 0xb5, 0x1c, 0x4c, 0x27, 0x5c, 0x78, 0x79, 0x58, + 0x54, 0x17, 0xb1, 0x24, 0x0e, 0x8b, 0xc6, 0x6a, 0x4f, 0x9e, 0x87, 0x09, 0x39, 0x40, 0x6a, 0xe0, + 0x43, 0x35, 0x22, 0x87, 0x10, 0x15, 0x96, 0x2b, 0x04, 0x15, 0x24, 0x4c, 0x2b, 0x04, 0x15, 0x45, + 0x44, 0x8d, 0x27, 0xef, 0x87, 0xb2, 0xee, 0x9d, 0x1a, 0xe9, 0xe8, 0x46, 0x28, 0x05, 0xc7, 0x90, + 0xc2, 0xf8, 0x72, 0x41, 0x2d, 0x0f, 0x99, 0xf3, 0xd3, 0x9e, 0xf5, 0x2f, 0x72, 0xe3, 0x2f, 0x9c, + 0x43, 0x27, 0x7a, 0xf9, 0x4f, 0x38, 0xb7, 0x62, 0x40, 0x8c, 0x4b, 0xe3, 0x83, 0x12, 0xab, 0xc6, + 0xa9, 0xc4, 0x75, 0xab, 0xa8, 0x9e, 0x51, 0x58, 0x75, 0x08, 0x65, 0x20, 0xed, 0x11, 0x3f, 0x84, + 0x12, 0x21, 0xd3, 0x29, 0x8f, 0x15, 0x38, 0xc7, 0x4d, 0xd1, 0x65, 0xdf, 0xeb, 0x36, 0x68, 0xdb, + 0x76, 0x5d, 0xdb, 0x6d, 0xab, 0x7c, 0x66, 0x98, 0x37, 0xc1, 0x34, 0x01, 0x0e, 0xb6, 0xd1, 0x51, + 0x81, 0xd2, 0x49, 0x47, 0x05, 0x8c, 0x2f, 0xe4, 0x41, 0x64, 0x31, 0xc8, 0x87, 0xa0, 0xd2, 0xa5, + 0xd6, 0xae, 0xe9, 0xda, 0x81, 0x3e, 0x95, 0xcf, 0x7d, 0xea, 0xca, 0xba, 0x06, 0x3e, 0xe4, 0xdf, + 0x76, 0xa1, 0xb9, 0x26, 0xea, 0x58, 0x22, 0x5a, 0x62, 0xc1, 0x44, 0x3b, 0x08, 0xcc, 0x9e, 0x3d, + 0xf6, 0xd5, 0x84, 0xf2, 0xdc, 0xb4, 0xd4, 0x6f, 0xf2, 0x37, 0x2a, 0xd6, 0xc4, 0x82, 0x52, 0xcf, + 0x31, 0x6d, 0x57, 0x39, 0x59, 0x8d, 0xb1, 0x72, 0x37, 0x1b, 0x9c, 0x93, 0x8c, 0x1e, 0x89, 0x9f, + 0x28, 0x79, 0x1b, 0xff, 0x91, 0x83, 0x4a, 0x88, 0x27, 0x5b, 0x00, 0x5c, 0x5d, 0xa8, 0xb3, 0xbf, + 0xc7, 0xba, 0x55, 0x4b, 0xf8, 0xc1, 0x5b, 0x61, 0x63, 0x8c, 0x31, 0xca, 0x38, 0x1c, 0x9d, 0x3f, + 0xe9, 0xc3, 0xd1, 0x37, 0xa0, 0xb2, 0x6b, 0xba, 0xad, 0x60, 0xd7, 0xec, 0x48, 0xad, 0x59, 0x8e, + 0x8c, 0xb4, 0x57, 0x35, 0x02, 0x23, 0x1a, 0xe3, 0x8f, 0x8b, 0x20, 0xaf, 0x9b, 0xe3, 0xeb, 0xba, + 0x65, 0x07, 0x32, 0xef, 0x9e, 0x13, 0x2d, 0xc3, 0x75, 0xbd, 0xa4, 0xe0, 0x18, 0x52, 0x90, 0xcb, + 0x50, 0xe8, 0xda, 0xae, 0x4a, 0x37, 0x88, 0x79, 0xb5, 0x6e, 0xbb, 0xc8, 0x61, 0x02, 0x65, 0x3e, + 0x50, 0xa9, 0x63, 0x89, 0x32, 0x1f, 0x20, 0x87, 0x71, 0xa7, 0xd3, 0xf1, 0xbc, 0xce, 0xb6, 0x69, + 0x75, 0x74, 0x4a, 0xac, 0x28, 0x76, 0x57, 0xe1, 0x74, 0xae, 0x25, 0x51, 0x98, 0xa6, 0xe5, 0xcd, + 0x2d, 0xcf, 0x73, 0x5a, 0xde, 0x7d, 0x57, 0x37, 0x2f, 0x45, 0xcd, 0x17, 0x93, 0x28, 0x4c, 0xd3, + 0x92, 0x2d, 0x78, 0xfa, 0x6d, 0xea, 0x7b, 0x4a, 0xa3, 0x35, 0x1d, 0x4a, 0x7b, 0x9a, 0x8d, 0x34, + 0x20, 0x44, 0x9e, 0xfb, 0x13, 0xd9, 0x24, 0x38, 0xac, 0xad, 0x48, 0x9f, 0x9b, 0x7e, 0x9b, 0xb2, + 0x0d, 0xdf, 0xb3, 0x68, 0x10, 0xd8, 0x6e, 0x5b, 0xb3, 0x9d, 0x8c, 0xd8, 0x6e, 0x66, 0x93, 0xe0, + 0xb0, 0xb6, 0xe4, 0x75, 0xa8, 0x49, 0x94, 0x34, 0x2c, 0x16, 0xf6, 0x4c, 0xdb, 0x31, 0xb7, 0x6d, + 0xc7, 0x66, 0xfb, 0xa2, 0xd8, 0x64, 0x5a, 0xe6, 0x04, 0x36, 0x87, 0xd0, 0xe0, 0xd0, 0xd6, 0xe2, + 0x3e, 0x58, 0x95, 0x11, 0xda, 0xa0, 0xbe, 0xf8, 0xfa, 0x22, 0xbc, 0xac, 0x7c, 0x77, 0x4c, 0xe1, + 0x70, 0x80, 0xda, 0xf8, 0x56, 0x1e, 0x2a, 0xa1, 0x31, 0x7c, 0x84, 0xab, 0x1e, 0x3c, 0xa8, 0x84, + 0x65, 0x07, 0x6a, 0xd2, 0x37, 0xc6, 0x4f, 0x3c, 0x48, 0xfb, 0x2d, 0x7c, 0xc4, 0x48, 0x46, 0xfc, + 0x2e, 0xc9, 0xc2, 0x18, 0x77, 0x49, 0xf6, 0x60, 0x92, 0xf9, 0x76, 0xbb, 0xad, 0x8c, 0x8a, 0xea, + 0xfc, 0xea, 0xf8, 0xee, 0xc4, 0xa6, 0x64, 0x28, 0xf3, 0xf1, 0xea, 0x01, 0xb5, 0x18, 0xe3, 0xeb, + 0x39, 0x38, 0x9b, 0x26, 0x15, 0x25, 0x4c, 0xd6, 0x2e, 0x6d, 0xf5, 0x9d, 0x70, 0x90, 0xc5, 0x76, + 0xab, 0x60, 0x18, 0x62, 0xc9, 0xeb, 0x50, 0x16, 0x3e, 0xfc, 0x5e, 0x68, 0x0c, 0x8e, 0x74, 0x37, + 0xc0, 0xaa, 0xe2, 0x81, 0x21, 0x37, 0xde, 0x07, 0x66, 0x77, 0xe9, 0xdb, 0x9e, 0xab, 0xcd, 0x31, + 0x41, 0xb9, 0xa9, 0x60, 0x18, 0x62, 0x8d, 0x7f, 0x2d, 0xc0, 0xe5, 0xc8, 0x53, 0x5a, 0x37, 0x5d, + 0xb3, 0x7d, 0x84, 0x3b, 0x48, 0x7f, 0x52, 0x9c, 0x73, 0xdc, 0x4b, 0x7d, 0x0a, 0x4f, 0xc0, 0xa5, + 0x3e, 0xbf, 0x55, 0x00, 0x71, 0xd3, 0x2f, 0xb7, 0x52, 0x1c, 0x4f, 0x1b, 0x72, 0xa3, 0x5b, 0x29, + 0x6b, 0x5e, 0x5b, 0x6e, 0x19, 0x6b, 0x5e, 0x1b, 0x39, 0x47, 0xbe, 0xfd, 0x77, 0xcc, 0x9d, 0x8e, + 0x39, 0xb6, 0xda, 0x08, 0x8b, 0x8a, 0xe4, 0xf6, 0x2f, 0x1e, 0x51, 0xf2, 0xe6, 0xfa, 0x69, 0x5b, + 0x5f, 0x55, 0x39, 0xb6, 0x9d, 0x11, 0x5e, 0x7a, 0x29, 0xf5, 0x53, 0xf8, 0x88, 0x91, 0x0c, 0x6e, + 0x39, 0xf5, 0x5b, 0xe2, 0xc6, 0xe5, 0xe2, 0x98, 0x96, 0xd3, 0xd6, 0x92, 0x78, 0x27, 0x61, 0x39, + 0xc9, 0xdf, 0xa8, 0x58, 0x1b, 0x7f, 0x92, 0x83, 0xe9, 0xa6, 0x63, 0xb7, 0x6c, 0xb7, 0x7d, 0x7a, + 0x17, 0x0e, 0x91, 0x3b, 0x50, 0x0a, 0x1c, 0xbb, 0x45, 0x47, 0xd4, 0x37, 0xe2, 0x63, 0xf0, 0x5e, + 0x52, 0x94, 0x7c, 0x8c, 0xaf, 0x96, 0x40, 0x5d, 0x4f, 0x4d, 0xfa, 0x50, 0x69, 0xeb, 0x8b, 0x51, + 0x54, 0x97, 0x5f, 0x1d, 0xe3, 0x00, 0x6d, 0xe2, 0x8a, 0x15, 0xf9, 0x75, 0x42, 0x20, 0x46, 0x92, + 0x08, 0x4d, 0xce, 0xb9, 0xa5, 0x31, 0xe7, 0x9c, 0x14, 0x37, 0x38, 0xeb, 0x4c, 0x28, 0xee, 0x32, + 0xd6, 0x53, 0x13, 0x6e, 0xf4, 0x43, 0x41, 0xd1, 0x79, 0x1f, 0x99, 0x98, 0xe3, 0xcf, 0x28, 0x58, + 0x73, 0x11, 0xae, 0x19, 0xde, 0xac, 0xb9, 0x38, 0x56, 0xe6, 0x2f, 0x2e, 0x82, 0x3f, 0xa3, 0x60, + 0x4d, 0x3e, 0x9b, 0x83, 0x29, 0x3f, 0xe6, 0xe1, 0x29, 0x4f, 0x65, 0xcc, 0x43, 0x15, 0x09, 0x77, + 0x51, 0x16, 0x0d, 0xc6, 0xe1, 0x98, 0x10, 0xc9, 0xdd, 0x49, 0xe6, 0x9b, 0x6e, 0xb0, 0xe3, 0xf9, + 0x5d, 0xea, 0x2b, 0x0f, 0x7c, 0x79, 0x8c, 0x35, 0xb5, 0x19, 0x71, 0x93, 0xb9, 0x94, 0x04, 0x08, + 0xe3, 0xd2, 0x8c, 0x2e, 0xa8, 0xa0, 0x1c, 0xb1, 0x12, 0x77, 0x93, 0xc9, 0xfa, 0xa9, 0x1b, 0x47, + 0x5b, 0x0f, 0xe1, 0xb5, 0x5a, 0xb1, 0xeb, 0x23, 0x32, 0x2f, 0x21, 0x33, 0xfe, 0x31, 0x0f, 0xdc, + 0x87, 0x93, 0xa7, 0xa1, 0xc5, 0xc5, 0x7f, 0xb4, 0xd9, 0xb1, 0x7b, 0x77, 0xa9, 0x6f, 0xef, 0xec, + 0x2b, 0xcb, 0x3d, 0x76, 0x1a, 0x3a, 0x4d, 0x81, 0x19, 0xad, 0xc8, 0x1b, 0x30, 0x65, 0x99, 0x8b, + 0xd4, 0x67, 0xa3, 0xf8, 0x25, 0xe2, 0xe3, 0x2c, 0x2e, 0x44, 0xcd, 0x31, 0xc1, 0x8c, 0x7b, 0x53, + 0x56, 0xc4, 0xba, 0x70, 0x6c, 0x6f, 0x2a, 0xc6, 0x38, 0xc6, 0x88, 0x20, 0x54, 0x3a, 0x9c, 0x54, + 0x70, 0x2d, 0x1e, 0x87, 0xab, 0x58, 0xf8, 0xb7, 0x74, 0x5b, 0x8c, 0xd8, 0x18, 0x2e, 0x4c, 0x27, + 0xae, 0x38, 0x23, 0x1f, 0x86, 0xb2, 0xd7, 0x8b, 0xe9, 0x9f, 0x8a, 0xa8, 0x18, 0x2a, 0xdf, 0x51, + 0xb0, 0x87, 0x07, 0xf5, 0xe9, 0x35, 0xaf, 0x6d, 0x5b, 0x1a, 0x80, 0x21, 0x39, 0x31, 0x60, 0x42, + 0x54, 0x77, 0xe9, 0x0b, 0xce, 0x84, 0xee, 0x14, 0x97, 0x1f, 0x05, 0xa8, 0x30, 0xc6, 0x17, 0x0b, + 0x10, 0x85, 0xb2, 0x49, 0x00, 0x13, 0x2d, 0x71, 0x11, 0x92, 0x52, 0x75, 0xa3, 0xa7, 0x04, 0x92, + 0x57, 0x2e, 0x4a, 0xcf, 0x31, 0x09, 0x43, 0x25, 0x8a, 0xb4, 0xa1, 0xf0, 0x96, 0xb7, 0x3d, 0xb6, + 0xa6, 0x8b, 0xd5, 0x5f, 0xcb, 0x38, 0x6c, 0x0c, 0x80, 0x5c, 0x02, 0xf9, 0xdd, 0x1c, 0x9c, 0x0b, + 0xd2, 0x66, 0xa1, 0x9a, 0x0e, 0x38, 0xbe, 0x59, 0x9d, 0x36, 0x34, 0x55, 0x69, 0xd7, 0x30, 0x34, + 0x0e, 0xf6, 0xc5, 0xf8, 0x95, 0x3c, 0x54, 0x63, 0xab, 0x7c, 0xec, 0x2b, 0xec, 0x1e, 0xa4, 0xae, + 0xb0, 0xdb, 0x18, 0x3d, 0x78, 0x13, 0xf5, 0xea, 0xb4, 0x6f, 0xb1, 0xfb, 0x9b, 0x3c, 0x14, 0xb6, + 0x96, 0x96, 0x93, 0x2e, 0x5b, 0xee, 0x5d, 0x70, 0xd9, 0x76, 0x61, 0x72, 0xbb, 0x6f, 0x3b, 0xcc, + 0x76, 0xc7, 0x3e, 0x97, 0xa0, 0x6f, 0xfc, 0x53, 0x35, 0xcf, 0x92, 0x2b, 0x6a, 0xf6, 0xa4, 0x0d, + 0x93, 0x6d, 0x79, 0x2e, 0x59, 0x4d, 0xbf, 0x57, 0x46, 0xb7, 0x29, 0x24, 0x1f, 0x29, 0x48, 0x3d, + 0xa0, 0xe6, 0x6e, 0x7c, 0x1a, 0x94, 0x49, 0x46, 0x82, 0xd3, 0x19, 0xcd, 0x30, 0xb6, 0x93, 0x35, + 0xa2, 0xc6, 0xbf, 0xe5, 0x20, 0xb9, 0x6f, 0xbd, 0xfb, 0x1f, 0xb5, 0x93, 0xfe, 0xa8, 0x4b, 0x27, + 0xb1, 0x06, 0xb2, 0xbf, 0xab, 0xf1, 0xf5, 0x3c, 0x4c, 0xa8, 0xbf, 0x55, 0x39, 0xfd, 0x2a, 0x13, + 0x9a, 0xa8, 0x32, 0x59, 0x1c, 0xf3, 0x3e, 0xee, 0xa1, 0x35, 0x26, 0xdd, 0x54, 0x8d, 0xc9, 0xb8, + 0x17, 0x7f, 0x3f, 0xa6, 0xc2, 0xe4, 0xef, 0x72, 0x30, 0x23, 0x09, 0x57, 0xdd, 0x80, 0x99, 0xae, + 0x25, 0x5c, 0x15, 0x99, 0x79, 0x1b, 0x3b, 0x95, 0xa9, 0xd2, 0xfd, 0x72, 0x23, 0x14, 0xbf, 0x51, + 0xb1, 0x26, 0xef, 0x87, 0xf2, 0xae, 0x17, 0x30, 0xa1, 0x6e, 0xf3, 0xc9, 0xa4, 0xc2, 0xab, 0x0a, + 0x8e, 0x21, 0x45, 0x3a, 0x5b, 0x51, 0x1a, 0x9e, 0xad, 0x30, 0xfe, 0x30, 0x0f, 0x53, 0x89, 0xeb, + 0xde, 0x47, 0x2e, 0x98, 0x49, 0xd5, 0xab, 0xe4, 0x4f, 0xbe, 0x5e, 0x25, 0xab, 0x26, 0xa7, 0x30, + 0x66, 0x4d, 0x4e, 0xf1, 0x38, 0x35, 0x39, 0xc6, 0x37, 0x73, 0x00, 0x7a, 0xb4, 0x4e, 0xbd, 0x5c, + 0xa6, 0x95, 0x2c, 0x97, 0x19, 0x7b, 0x5e, 0x65, 0x17, 0xcb, 0xfc, 0x45, 0x49, 0xbf, 0x92, 0x28, + 0x95, 0x79, 0x27, 0x07, 0x33, 0x66, 0xa2, 0xfc, 0x64, 0x6c, 0x63, 0x2b, 0x55, 0xcd, 0x12, 0xfe, + 0xf1, 0x4a, 0x12, 0x8e, 0x29, 0xb1, 0xe4, 0x25, 0x98, 0xea, 0xa9, 0xdc, 0xfc, 0xed, 0x68, 0xda, + 0x87, 0x67, 0xe4, 0x36, 0x62, 0x38, 0x4c, 0x50, 0x3e, 0xa6, 0xdc, 0xa7, 0x70, 0x22, 0xe5, 0x3e, + 0xf1, 0x33, 0x05, 0xc5, 0x47, 0x9e, 0x29, 0xd8, 0x83, 0xca, 0x8e, 0xef, 0x75, 0x45, 0x45, 0x8d, + 0xba, 0x32, 0xfc, 0xe6, 0x18, 0x7b, 0x4a, 0xf4, 0x67, 0x19, 0xd1, 0xee, 0xb6, 0xac, 0xf9, 0x63, + 0x24, 0x4a, 0xc4, 0x66, 0x3d, 0x29, 0x75, 0xe2, 0x24, 0xa5, 0x86, 0xba, 0x64, 0x53, 0x72, 0x47, + 0x2d, 0x26, 0x59, 0x45, 0x33, 0xf9, 0xee, 0x54, 0xd1, 0x18, 0xdf, 0x0a, 0x15, 0x58, 0x33, 0x75, + 0x8c, 0x3e, 0x37, 0xe4, 0x18, 0xbd, 0xba, 0xce, 0x26, 0x5e, 0xef, 0xf1, 0x3c, 0x4c, 0xf8, 0xd4, + 0x0c, 0x3c, 0x57, 0xdd, 0x96, 0x15, 0xaa, 0x7f, 0x14, 0x50, 0x54, 0xd8, 0x78, 0x5d, 0x48, 0xfe, + 0x31, 0x75, 0x21, 0xef, 0x8f, 0x4d, 0x10, 0x59, 0xf8, 0x17, 0xae, 0xf5, 0x8c, 0x49, 0x22, 0x92, + 0xc6, 0xea, 0xdf, 0x14, 0x4b, 0xe9, 0xa4, 0xb1, 0xfa, 0xa7, 0xc3, 0x90, 0x82, 0xb4, 0x60, 0xca, + 0x31, 0x03, 0x26, 0x72, 0x0d, 0xad, 0x05, 0x36, 0x42, 0xd1, 0x49, 0xb8, 0x8c, 0xd6, 0x62, 0x7c, + 0x30, 0xc1, 0xd5, 0xf8, 0xcd, 0x1c, 0x44, 0x43, 0x7e, 0xcc, 0xf4, 0xd7, 0xeb, 0x50, 0xee, 0x9a, + 0x0f, 0x96, 0xa8, 0x63, 0xee, 0x8f, 0x13, 0x67, 0x5f, 0x57, 0x3c, 0x30, 0xe4, 0x66, 0x1c, 0xe4, + 0x40, 0xdd, 0x69, 0x43, 0x28, 0x94, 0x76, 0xec, 0x07, 0xaa, 0x3f, 0xe3, 0x98, 0x4e, 0xb1, 0x3b, + 0xc7, 0x65, 0x18, 0x4a, 0x00, 0x50, 0x72, 0x27, 0x5d, 0x98, 0x0c, 0x64, 0x94, 0x50, 0xbd, 0xca, + 0xe8, 0x81, 0x93, 0x44, 0xb4, 0x51, 0xdd, 0x50, 0x23, 0x41, 0xa8, 0x65, 0x34, 0xe6, 0xbe, 0xf1, + 0xdd, 0xab, 0x4f, 0x7d, 0xf3, 0xbb, 0x57, 0x9f, 0xfa, 0xf6, 0x77, 0xaf, 0x3e, 0xf5, 0x99, 0xc3, + 0xab, 0xb9, 0x6f, 0x1c, 0x5e, 0xcd, 0x7d, 0xf3, 0xf0, 0x6a, 0xee, 0xdb, 0x87, 0x57, 0x73, 0xff, + 0x7c, 0x78, 0x35, 0xf7, 0xeb, 0xff, 0x72, 0xf5, 0xa9, 0x4f, 0x94, 0x35, 0xcf, 0xff, 0x0e, 0x00, + 0x00, 0xff, 0xff, 0xee, 0x1c, 0xf1, 0xc8, 0xbd, 0x75, 0x00, 0x00, } func (m *AbstractPodTemplate) Marshal() (dAtA []byte, err error) { @@ -2730,6 +2862,27 @@ func (m *AbstractVertex) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.SideInputsContainerTemplate != nil { + { + size, err := m.SideInputsContainerTemplate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x7a + } + if len(m.SideInputs) > 0 { + for iNdEx := len(m.SideInputs) - 1; iNdEx >= 0; iNdEx-- { + i -= len(m.SideInputs[iNdEx]) + copy(dAtA[i:], m.SideInputs[iNdEx]) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.SideInputs[iNdEx]))) + i-- + dAtA[i] = 0x72 + } + } if m.Partitions != nil { i = encodeVarintGenerated(dAtA, i, uint64(*m.Partitions)) i-- @@ -4071,6 +4224,58 @@ func (m *GetRedisStatefulSetSpecReq) MarshalToSizedBuffer(dAtA []byte) (int, err return len(dAtA) - i, nil } +func (m *GetSideInputDeploymentReq) 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 *GetSideInputDeploymentReq) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *GetSideInputDeploymentReq) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if len(m.Env) > 0 { + for iNdEx := len(m.Env) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Env[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + } + i -= len(m.PullPolicy) + copy(dAtA[i:], m.PullPolicy) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.PullPolicy))) + i-- + dAtA[i] = 0x1a + i -= len(m.Image) + copy(dAtA[i:], m.Image) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.Image))) + i-- + dAtA[i] = 0x12 + i -= len(m.ISBSvcType) + copy(dAtA[i:], m.ISBSvcType) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.ISBSvcType))) + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + func (m *GetVertexPodSpecReq) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) @@ -4091,6 +4296,11 @@ func (m *GetVertexPodSpecReq) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + i -= len(m.SideInputsStoreName) + copy(dAtA[i:], m.SideInputsStoreName) + i = encodeVarintGenerated(dAtA, i, uint64(len(m.SideInputsStoreName))) + i-- + dAtA[i] = 0x2a if len(m.Env) > 0 { for iNdEx := len(m.Env) - 1; iNdEx >= 0; iNdEx-- { { @@ -5440,6 +5650,20 @@ func (m *PipelineSpec) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if len(m.SideInputs) > 0 { + for iNdEx := len(m.SideInputs) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.SideInputs[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x42 + } + } if m.Templates != nil { { size, err := m.Templates.MarshalToSizedBuffer(dAtA[:i]) @@ -5993,7 +6217,7 @@ func (m *Scale) MarshalToSizedBuffer(dAtA []byte) (int, error) { return len(dAtA) - i, nil } -func (m *Sink) Marshal() (dAtA []byte, err error) { +func (m *SideInput) Marshal() (dAtA []byte, err error) { size := m.Size() dAtA = make([]byte, size) n, err := m.MarshalToSizedBuffer(dAtA[:size]) @@ -6003,19 +6227,19 @@ func (m *Sink) Marshal() (dAtA []byte, err error) { return dAtA[:n], nil } -func (m *Sink) MarshalTo(dAtA []byte) (int, error) { +func (m *SideInput) MarshalTo(dAtA []byte) (int, error) { size := m.Size() return m.MarshalToSizedBuffer(dAtA[:size]) } -func (m *Sink) MarshalToSizedBuffer(dAtA []byte) (int, error) { +func (m *SideInput) MarshalToSizedBuffer(dAtA []byte) (int, error) { i := len(dAtA) _ = i var l int _ = l - if m.UDSink != nil { + if m.Trigger != nil { { - size, err := m.UDSink.MarshalToSizedBuffer(dAtA[:i]) + size, err := m.Trigger.MarshalToSizedBuffer(dAtA[:i]) if err != nil { return 0, err } @@ -6025,17 +6249,189 @@ func (m *Sink) MarshalToSizedBuffer(dAtA []byte) (int, error) { i-- dAtA[i] = 0x22 } - if m.Blackhole != nil { - { - size, err := m.Blackhole.MarshalToSizedBuffer(dAtA[:i]) - if err != nil { - return 0, err - } - i -= size - i = encodeVarintGenerated(dAtA, i, uint64(size)) - } - i-- - dAtA[i] = 0x1a + if len(m.Volumes) > 0 { + for iNdEx := len(m.Volumes) - 1; iNdEx >= 0; iNdEx-- { + { + size, err := m.Volumes[iNdEx].MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + } + if m.Container != nil { + { + size, err := m.Container.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + 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 *SideInputTrigger) 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 *SideInputTrigger) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SideInputTrigger) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.Timezone != nil { + i -= len(*m.Timezone) + copy(dAtA[i:], *m.Timezone) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Timezone))) + i-- + dAtA[i] = 0x1a + } + if m.Interval != nil { + { + size, err := m.Interval.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + if m.Schedule != nil { + i -= len(*m.Schedule) + copy(dAtA[i:], *m.Schedule) + i = encodeVarintGenerated(dAtA, i, uint64(len(*m.Schedule))) + i-- + dAtA[i] = 0xa + } + return len(dAtA) - i, nil +} + +func (m *SideInputsManagerTemplate) 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 *SideInputsManagerTemplate) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *SideInputsManagerTemplate) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.InitContainerTemplate != nil { + { + size, err := m.InitContainerTemplate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } + if m.ContainerTemplate != nil { + { + size, err := m.ContainerTemplate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x12 + } + { + size, err := m.AbstractPodTemplate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0xa + return len(dAtA) - i, nil +} + +func (m *Sink) 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 *Sink) MarshalTo(dAtA []byte) (int, error) { + size := m.Size() + return m.MarshalToSizedBuffer(dAtA[:size]) +} + +func (m *Sink) MarshalToSizedBuffer(dAtA []byte) (int, error) { + i := len(dAtA) + _ = i + var l int + _ = l + if m.UDSink != nil { + { + size, err := m.UDSink.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x22 + } + if m.Blackhole != nil { + { + size, err := m.Blackhole.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a } if m.Kafka != nil { { @@ -6369,6 +6765,18 @@ func (m *Templates) MarshalToSizedBuffer(dAtA []byte) (int, error) { _ = i var l int _ = l + if m.SideInputsManagerTemplate != nil { + { + size, err := m.SideInputsManagerTemplate.MarshalToSizedBuffer(dAtA[:i]) + if err != nil { + return 0, err + } + i -= size + i = encodeVarintGenerated(dAtA, i, uint64(size)) + } + i-- + dAtA[i] = 0x1a + } if m.JobTemplate != nil { { size, err := m.JobTemplate.MarshalToSizedBuffer(dAtA[:i]) @@ -7150,6 +7558,16 @@ func (m *AbstractVertex) Size() (n int) { if m.Partitions != nil { n += 1 + sovGenerated(uint64(*m.Partitions)) } + if len(m.SideInputs) > 0 { + for _, s := range m.SideInputs { + l = len(s) + n += 1 + l + sovGenerated(uint64(l)) + } + } + if m.SideInputsContainerTemplate != nil { + l = m.SideInputsContainerTemplate.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -7611,6 +8029,27 @@ func (m *GetRedisStatefulSetSpecReq) Size() (n int) { return n } +func (m *GetSideInputDeploymentReq) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + l = len(m.ISBSvcType) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.Image) + n += 1 + l + sovGenerated(uint64(l)) + l = len(m.PullPolicy) + n += 1 + l + sovGenerated(uint64(l)) + if len(m.Env) > 0 { + for _, e := range m.Env { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + return n +} + func (m *GetVertexPodSpecReq) Size() (n int) { if m == nil { return 0 @@ -7629,6 +8068,8 @@ func (m *GetVertexPodSpecReq) Size() (n int) { n += 1 + l + sovGenerated(uint64(l)) } } + l = len(m.SideInputsStoreName) + n += 1 + l + sovGenerated(uint64(l)) return n } @@ -8133,6 +8574,12 @@ func (m *PipelineSpec) Size() (n int) { l = m.Templates.Size() n += 1 + l + sovGenerated(uint64(l)) } + if len(m.SideInputs) > 0 { + for _, e := range m.SideInputs { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } return n } @@ -8317,64 +8764,129 @@ func (m *Scale) Size() (n int) { return n } -func (m *Sink) Size() (n int) { +func (m *SideInput) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.Log != nil { - l = m.Log.Size() + l = len(m.Name) + n += 1 + l + sovGenerated(uint64(l)) + if m.Container != nil { + l = m.Container.Size() n += 1 + l + sovGenerated(uint64(l)) } - if m.Kafka != nil { - l = m.Kafka.Size() + if len(m.Volumes) > 0 { + for _, e := range m.Volumes { + l = e.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + } + if m.Trigger != nil { + l = m.Trigger.Size() n += 1 + l + sovGenerated(uint64(l)) } - if m.Blackhole != nil { - l = m.Blackhole.Size() + return n +} + +func (m *SideInputTrigger) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Schedule != nil { + l = len(*m.Schedule) n += 1 + l + sovGenerated(uint64(l)) } - if m.UDSink != nil { - l = m.UDSink.Size() + if m.Interval != nil { + l = m.Interval.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Timezone != nil { + l = len(*m.Timezone) n += 1 + l + sovGenerated(uint64(l)) } return n } -func (m *SlidingWindow) Size() (n int) { +func (m *SideInputsManagerTemplate) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.Length != nil { - l = m.Length.Size() + l = m.AbstractPodTemplate.Size() + n += 1 + l + sovGenerated(uint64(l)) + if m.ContainerTemplate != nil { + l = m.ContainerTemplate.Size() n += 1 + l + sovGenerated(uint64(l)) } - if m.Slide != nil { - l = m.Slide.Size() + if m.InitContainerTemplate != nil { + l = m.InitContainerTemplate.Size() n += 1 + l + sovGenerated(uint64(l)) } return n } -func (m *Source) Size() (n int) { +func (m *Sink) Size() (n int) { if m == nil { return 0 } var l int _ = l - if m.Generator != nil { - l = m.Generator.Size() + if m.Log != nil { + l = m.Log.Size() n += 1 + l + sovGenerated(uint64(l)) } if m.Kafka != nil { l = m.Kafka.Size() n += 1 + l + sovGenerated(uint64(l)) } - if m.HTTP != nil { - l = m.HTTP.Size() + if m.Blackhole != nil { + l = m.Blackhole.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.UDSink != nil { + l = m.UDSink.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *SlidingWindow) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Length != nil { + l = m.Length.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Slide != nil { + l = m.Slide.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + return n +} + +func (m *Source) Size() (n int) { + if m == nil { + return 0 + } + var l int + _ = l + if m.Generator != nil { + l = m.Generator.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.Kafka != nil { + l = m.Kafka.Size() + n += 1 + l + sovGenerated(uint64(l)) + } + if m.HTTP != nil { + l = m.HTTP.Size() n += 1 + l + sovGenerated(uint64(l)) } if m.Nats != nil { @@ -8462,6 +8974,10 @@ func (m *Templates) Size() (n int) { l = m.JobTemplate.Size() n += 1 + l + sovGenerated(uint64(l)) } + if m.SideInputsManagerTemplate != nil { + l = m.SideInputsManagerTemplate.Size() + n += 1 + l + sovGenerated(uint64(l)) + } return n } @@ -8773,6 +9289,8 @@ func (this *AbstractVertex) String() string { `InitContainers:` + repeatedStringForInitContainers + `,`, `Sidecars:` + repeatedStringForSidecars + `,`, `Partitions:` + valueToStringGenerated(this.Partitions) + `,`, + `SideInputs:` + fmt.Sprintf("%v", this.SideInputs) + `,`, + `SideInputsContainerTemplate:` + strings.Replace(this.SideInputsContainerTemplate.String(), "ContainerTemplate", "ContainerTemplate", 1) + `,`, `}`, }, "") return s @@ -9120,6 +9638,24 @@ func (this *GetRedisStatefulSetSpecReq) String() string { }, "") return s } +func (this *GetSideInputDeploymentReq) String() string { + if this == nil { + return "nil" + } + repeatedStringForEnv := "[]EnvVar{" + for _, f := range this.Env { + repeatedStringForEnv += fmt.Sprintf("%v", f) + "," + } + repeatedStringForEnv += "}" + s := strings.Join([]string{`&GetSideInputDeploymentReq{`, + `ISBSvcType:` + fmt.Sprintf("%v", this.ISBSvcType) + `,`, + `Image:` + fmt.Sprintf("%v", this.Image) + `,`, + `PullPolicy:` + fmt.Sprintf("%v", this.PullPolicy) + `,`, + `Env:` + repeatedStringForEnv + `,`, + `}`, + }, "") + return s +} func (this *GetVertexPodSpecReq) String() string { if this == nil { return "nil" @@ -9134,6 +9670,7 @@ func (this *GetVertexPodSpecReq) String() string { `Image:` + fmt.Sprintf("%v", this.Image) + `,`, `PullPolicy:` + fmt.Sprintf("%v", this.PullPolicy) + `,`, `Env:` + repeatedStringForEnv + `,`, + `SideInputsStoreName:` + fmt.Sprintf("%v", this.SideInputsStoreName) + `,`, `}`, }, "") return s @@ -9464,6 +10001,11 @@ func (this *PipelineSpec) String() string { repeatedStringForEdges += strings.Replace(strings.Replace(f.String(), "Edge", "Edge", 1), `&`, ``, 1) + "," } repeatedStringForEdges += "}" + repeatedStringForSideInputs := "[]SideInput{" + for _, f := range this.SideInputs { + repeatedStringForSideInputs += strings.Replace(strings.Replace(f.String(), "SideInput", "SideInput", 1), `&`, ``, 1) + "," + } + repeatedStringForSideInputs += "}" s := strings.Join([]string{`&PipelineSpec{`, `InterStepBufferServiceName:` + fmt.Sprintf("%v", this.InterStepBufferServiceName) + `,`, `Vertices:` + repeatedStringForVertices + `,`, @@ -9472,6 +10014,7 @@ func (this *PipelineSpec) String() string { `Limits:` + strings.Replace(this.Limits.String(), "PipelineLimits", "PipelineLimits", 1) + `,`, `Watermark:` + strings.Replace(strings.Replace(this.Watermark.String(), "Watermark", "Watermark", 1), `&`, ``, 1) + `,`, `Templates:` + strings.Replace(this.Templates.String(), "Templates", "Templates", 1) + `,`, + `SideInputs:` + repeatedStringForSideInputs + `,`, `}`, }, "") return s @@ -9588,6 +10131,48 @@ func (this *Scale) String() string { }, "") return s } +func (this *SideInput) String() string { + if this == nil { + return "nil" + } + repeatedStringForVolumes := "[]Volume{" + for _, f := range this.Volumes { + repeatedStringForVolumes += fmt.Sprintf("%v", f) + "," + } + repeatedStringForVolumes += "}" + s := strings.Join([]string{`&SideInput{`, + `Name:` + fmt.Sprintf("%v", this.Name) + `,`, + `Container:` + strings.Replace(this.Container.String(), "Container", "Container", 1) + `,`, + `Volumes:` + repeatedStringForVolumes + `,`, + `Trigger:` + strings.Replace(this.Trigger.String(), "SideInputTrigger", "SideInputTrigger", 1) + `,`, + `}`, + }, "") + return s +} +func (this *SideInputTrigger) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SideInputTrigger{`, + `Schedule:` + valueToStringGenerated(this.Schedule) + `,`, + `Interval:` + strings.Replace(fmt.Sprintf("%v", this.Interval), "Duration", "v11.Duration", 1) + `,`, + `Timezone:` + valueToStringGenerated(this.Timezone) + `,`, + `}`, + }, "") + return s +} +func (this *SideInputsManagerTemplate) String() string { + if this == nil { + return "nil" + } + s := strings.Join([]string{`&SideInputsManagerTemplate{`, + `AbstractPodTemplate:` + strings.Replace(strings.Replace(this.AbstractPodTemplate.String(), "AbstractPodTemplate", "AbstractPodTemplate", 1), `&`, ``, 1) + `,`, + `ContainerTemplate:` + strings.Replace(this.ContainerTemplate.String(), "ContainerTemplate", "ContainerTemplate", 1) + `,`, + `InitContainerTemplate:` + strings.Replace(this.InitContainerTemplate.String(), "ContainerTemplate", "ContainerTemplate", 1) + `,`, + `}`, + }, "") + return s +} func (this *Sink) String() string { if this == nil { return "nil" @@ -9673,6 +10258,7 @@ func (this *Templates) String() string { s := strings.Join([]string{`&Templates{`, `DaemonTemplate:` + strings.Replace(this.DaemonTemplate.String(), "DaemonTemplate", "DaemonTemplate", 1) + `,`, `JobTemplate:` + strings.Replace(this.JobTemplate.String(), "JobTemplate", "JobTemplate", 1) + `,`, + `SideInputsManagerTemplate:` + strings.Replace(this.SideInputsManagerTemplate.String(), "SideInputsManagerTemplate", "SideInputsManagerTemplate", 1) + `,`, `}`, }, "") return s @@ -10880,6 +11466,74 @@ func (m *AbstractVertex) Unmarshal(dAtA []byte) error { } } m.Partitions = &v + case 14: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SideInputs", 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.SideInputs = append(m.SideInputs, string(dAtA[iNdEx:postIndex])) + iNdEx = postIndex + case 15: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SideInputsContainerTemplate", 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.SideInputsContainerTemplate == nil { + m.SideInputsContainerTemplate = &ContainerTemplate{} + } + if err := m.SideInputsContainerTemplate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -15100,7 +15754,7 @@ func (m *GetRedisStatefulSetSpecReq) Unmarshal(dAtA []byte) error { } return nil } -func (m *GetVertexPodSpecReq) Unmarshal(dAtA []byte) error { +func (m *GetSideInputDeploymentReq) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -15123,10 +15777,10 @@ func (m *GetVertexPodSpecReq) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GetVertexPodSpecReq: wiretype end group for non-group") + return fmt.Errorf("proto: GetSideInputDeploymentReq: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GetVertexPodSpecReq: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: GetSideInputDeploymentReq: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: @@ -15280,7 +15934,7 @@ func (m *GetVertexPodSpecReq) Unmarshal(dAtA []byte) error { } return nil } -func (m *GroupBy) Unmarshal(dAtA []byte) error { +func (m *GetVertexPodSpecReq) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -15303,17 +15957,17 @@ func (m *GroupBy) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: GroupBy: wiretype end group for non-group") + return fmt.Errorf("proto: GetVertexPodSpecReq: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: GroupBy: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: GetVertexPodSpecReq: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Window", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field ISBSvcType", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -15323,30 +15977,29 @@ func (m *GroupBy) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if err := m.Window.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.ISBSvcType = ISBSvcType(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: - if wireType != 0 { - return fmt.Errorf("proto: wrong wireType = %d for field Keyed", wireType) + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Image", wireType) } - var v int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -15356,17 +16009,29 @@ func (m *GroupBy) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - v |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - m.Keyed = bool(v != 0) + intStringLen := int(stringLen) + if intStringLen < 0 { + return ErrInvalidLengthGenerated + } + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.Image = string(dAtA[iNdEx:postIndex]) + iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field AllowedLateness", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field PullPolicy", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -15376,31 +16041,27 @@ func (m *GroupBy) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if m.AllowedLateness == nil { - m.AllowedLateness = &v11.Duration{} - } - if err := m.AllowedLateness.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.PullPolicy = k8s_io_api_core_v1.PullPolicy(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 4: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Storage", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Env", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -15427,24 +16088,229 @@ func (m *GroupBy) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Storage == nil { - m.Storage = &PBQStorage{} - } - if err := m.Storage.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + m.Env = append(m.Env, v1.EnvVar{}) + if err := m.Env[len(m.Env)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex - default: - iNdEx = preIndex - skippy, err := skipGenerated(dAtA[iNdEx:]) - if err != nil { - return err + case 5: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SideInputsStoreName", wireType) } - if (skippy < 0) || (iNdEx+skippy) < 0 { + 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 } - if (iNdEx + skippy) > l { - return io.ErrUnexpectedEOF + postIndex := iNdEx + intStringLen + if postIndex < 0 { + return ErrInvalidLengthGenerated + } + if postIndex > l { + return io.ErrUnexpectedEOF + } + m.SideInputsStoreName = 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 *GroupBy) 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: GroupBy: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: GroupBy: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Window", 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 err := m.Window.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 0 { + return fmt.Errorf("proto: wrong wireType = %d for field Keyed", wireType) + } + var v int + for shift := uint(0); ; shift += 7 { + if shift >= 64 { + return ErrIntOverflowGenerated + } + if iNdEx >= l { + return io.ErrUnexpectedEOF + } + b := dAtA[iNdEx] + iNdEx++ + v |= int(b&0x7F) << shift + if b < 0x80 { + break + } + } + m.Keyed = bool(v != 0) + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AllowedLateness", 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.AllowedLateness == nil { + m.AllowedLateness = &v11.Duration{} + } + if err := m.AllowedLateness.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Storage", 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.Storage == nil { + m.Storage = &PBQStorage{} + } + if err := m.Storage.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + 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 } @@ -19511,6 +20377,40 @@ func (m *PipelineSpec) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 8: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SideInputs", 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 + } + m.SideInputs = append(m.SideInputs, SideInput{}) + if err := m.SideInputs[len(m.SideInputs)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) @@ -21072,7 +21972,7 @@ func (m *Scale) Unmarshal(dAtA []byte) error { } return nil } -func (m *Sink) Unmarshal(dAtA []byte) error { +func (m *SideInput) Unmarshal(dAtA []byte) error { l := len(dAtA) iNdEx := 0 for iNdEx < l { @@ -21095,17 +21995,17 @@ func (m *Sink) Unmarshal(dAtA []byte) error { fieldNum := int32(wire >> 3) wireType := int(wire & 0x7) if wireType == 4 { - return fmt.Errorf("proto: Sink: wiretype end group for non-group") + return fmt.Errorf("proto: SideInput: wiretype end group for non-group") } if fieldNum <= 0 { - return fmt.Errorf("proto: Sink: illegal tag %d (wire type %d)", fieldNum, wire) + return fmt.Errorf("proto: SideInput: illegal tag %d (wire type %d)", fieldNum, wire) } switch fieldNum { case 1: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Log", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Name", wireType) } - var msglen int + var stringLen uint64 for shift := uint(0); ; shift += 7 { if shift >= 64 { return ErrIntOverflowGenerated @@ -21115,31 +22015,27 @@ func (m *Sink) Unmarshal(dAtA []byte) error { } b := dAtA[iNdEx] iNdEx++ - msglen |= int(b&0x7F) << shift + stringLen |= uint64(b&0x7F) << shift if b < 0x80 { break } } - if msglen < 0 { + intStringLen := int(stringLen) + if intStringLen < 0 { return ErrInvalidLengthGenerated } - postIndex := iNdEx + msglen + postIndex := iNdEx + intStringLen if postIndex < 0 { return ErrInvalidLengthGenerated } if postIndex > l { return io.ErrUnexpectedEOF } - if m.Log == nil { - m.Log = &Log{} - } - if err := m.Log.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { - return err - } + m.Name = string(dAtA[iNdEx:postIndex]) iNdEx = postIndex case 2: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Kafka", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Container", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -21166,16 +22062,515 @@ func (m *Sink) Unmarshal(dAtA []byte) error { if postIndex > l { return io.ErrUnexpectedEOF } - if m.Kafka == nil { - m.Kafka = &KafkaSink{} + if m.Container == nil { + m.Container = &Container{} } - if err := m.Kafka.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + if err := m.Container.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { return err } iNdEx = postIndex case 3: if wireType != 2 { - return fmt.Errorf("proto: wrong wireType = %d for field Blackhole", wireType) + return fmt.Errorf("proto: wrong wireType = %d for field Volumes", 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 + } + m.Volumes = append(m.Volumes, v1.Volume{}) + if err := m.Volumes[len(m.Volumes)-1].Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 4: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Trigger", 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.Trigger == nil { + m.Trigger = &SideInputTrigger{} + } + if err := m.Trigger.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + 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 *SideInputTrigger) 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: SideInputTrigger: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SideInputTrigger: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Schedule", 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 + } + s := string(dAtA[iNdEx:postIndex]) + m.Schedule = &s + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Interval", 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.Interval == nil { + m.Interval = &v11.Duration{} + } + if err := m.Interval.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Timezone", 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 + } + s := string(dAtA[iNdEx:postIndex]) + m.Timezone = &s + 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 *SideInputsManagerTemplate) 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: SideInputsManagerTemplate: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: SideInputsManagerTemplate: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field AbstractPodTemplate", 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 err := m.AbstractPodTemplate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field ContainerTemplate", 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.ContainerTemplate == nil { + m.ContainerTemplate = &ContainerTemplate{} + } + if err := m.ContainerTemplate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field InitContainerTemplate", 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.InitContainerTemplate == nil { + m.InitContainerTemplate = &ContainerTemplate{} + } + if err := m.InitContainerTemplate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + 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 *Sink) 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: Sink: wiretype end group for non-group") + } + if fieldNum <= 0 { + return fmt.Errorf("proto: Sink: illegal tag %d (wire type %d)", fieldNum, wire) + } + switch fieldNum { + case 1: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Log", 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.Log == nil { + m.Log = &Log{} + } + if err := m.Log.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 2: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Kafka", 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.Kafka == nil { + m.Kafka = &KafkaSink{} + } + if err := m.Kafka.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field Blackhole", wireType) } var msglen int for shift := uint(0); ; shift += 7 { @@ -22132,6 +23527,42 @@ func (m *Templates) Unmarshal(dAtA []byte) error { return err } iNdEx = postIndex + case 3: + if wireType != 2 { + return fmt.Errorf("proto: wrong wireType = %d for field SideInputsManagerTemplate", 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.SideInputsManagerTemplate == nil { + m.SideInputsManagerTemplate = &SideInputsManagerTemplate{} + } + if err := m.SideInputsManagerTemplate.Unmarshal(dAtA[iNdEx:postIndex]); err != nil { + return err + } + iNdEx = postIndex default: iNdEx = preIndex skippy, err := skipGenerated(dAtA[iNdEx:]) diff --git a/pkg/apis/numaflow/v1alpha1/generated.proto b/pkg/apis/numaflow/v1alpha1/generated.proto index 972288703..ed1d4ab90 100644 --- a/pkg/apis/numaflow/v1alpha1/generated.proto +++ b/pkg/apis/numaflow/v1alpha1/generated.proto @@ -128,9 +128,11 @@ message AbstractVertex { // +optional optional UDF udf = 4; + // Container template for the main numa container. // +optional optional ContainerTemplate containerTemplate = 5; + // Container template for all the vertex pod init containers spawned by numaflow, excluding the ones specified by the user. // +optional optional ContainerTemplate initContainerTemplate = 6; @@ -150,12 +152,12 @@ message AbstractVertex { // +optional optional Scale scale = 10; - // List of init containers belonging to the pod. + // List of customized init containers belonging to the pod. // More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ // +optional repeated k8s.io.api.core.v1.Container initContainers = 11; - // List of sidecar containers belonging to the pod. + // List of customized sidecar containers belonging to the pod. // +optional repeated k8s.io.api.core.v1.Container sidecars = 12; @@ -163,6 +165,14 @@ message AbstractVertex { // It applies to udf and sink vertices only. // +optional optional int32 partitions = 13; + + // Names of the side inputs used in this vertex. + // +optional + repeated string sideInputs = 14; + + // Container template for the side inputs watcher container. + // +optional + optional ContainerTemplate sideInputsContainerTemplate = 15; } message Authorization { @@ -463,6 +473,16 @@ message GetRedisStatefulSetSpecReq { optional string healthConfigMapName = 15; } +message GetSideInputDeploymentReq { + optional string isbSvcType = 1; + + optional string image = 2; + + optional string pullPolicy = 3; + + repeated k8s.io.api.core.v1.EnvVar env = 4; +} + message GetVertexPodSpecReq { optional string isbSvcType = 1; @@ -471,6 +491,8 @@ message GetVertexPodSpecReq { optional string pullPolicy = 3; repeated k8s.io.api.core.v1.EnvVar env = 4; + + optional string sideInputsStoreName = 5; } // GroupBy indicates it is a reducer UDF @@ -818,12 +840,12 @@ message Pipeline { } message PipelineLimits { - // Read batch size for all the vertices in the pipeline, can be overridden by the vertex's limit settings + // Read batch size for all the vertices in the pipeline, can be overridden by the vertex's limit settings. // +kubebuilder:default=500 // +optional optional uint64 readBatchSize = 1; - // BufferMaxLength is used to define the max length of a buffer + // BufferMaxLength is used to define the max length of a buffer. // Only applies to UDF and Source vertices as only they do buffer write. // It can be overridden by the settings in vertex limits. // +kubebuilder:default=30000 @@ -880,6 +902,10 @@ message PipelineSpec { // Templates is used to customize additional kubernetes resources required for the Pipeline // +optional optional Templates templates = 7; + + // SideInputs defines the Side Inputs of a pipeline. + // +optional + repeated SideInput sideInputs = 8; } message PipelineStatus { @@ -1036,6 +1062,44 @@ message Scale { optional uint32 replicasPerScale = 9; } +// SideInput defines information of a Side Input +message SideInput { + optional string name = 1; + + optional Container container = 2; + + // +optional + // +patchStrategy=merge + // +patchMergeKey=name + repeated k8s.io.api.core.v1.Volume volumes = 3; + + optional SideInputTrigger trigger = 4; +} + +message SideInputTrigger { + // +optional + optional string schedule = 1; + + // +optional + optional k8s.io.apimachinery.pkg.apis.meta.v1.Duration interval = 2; + + // +optional + optional string timezone = 3; +} + +message SideInputsManagerTemplate { + // +optional + optional AbstractPodTemplate abstractPodTemplate = 1; + + // Template for the side inputs manager numa container + // +optional + optional ContainerTemplate containerTemplate = 2; + + // Template for the side inputs manager init container + // +optional + optional ContainerTemplate initContainerTemplate = 3; +} + message Sink { optional Log log = 1; @@ -1111,13 +1175,17 @@ message TagConditions { } message Templates { - // DaemonTemplate is used to customize the Daemon Deployment + // DaemonTemplate is used to customize the Daemon Deployment. // +optional optional DaemonTemplate daemon = 1; - // JobTemplate is used to customize Jobs + // JobTemplate is used to customize Jobs. // +optional optional JobTemplate job = 2; + + // SideInputsManagerTemplate is used to customize the Side Inputs Manager. + // +optional + optional SideInputsManagerTemplate sideInputsManager = 3; } message Transformer { diff --git a/pkg/apis/numaflow/v1alpha1/get_spec_req.go b/pkg/apis/numaflow/v1alpha1/get_spec_req.go index 9d1e15a19..8b8ee026a 100644 --- a/pkg/apis/numaflow/v1alpha1/get_spec_req.go +++ b/pkg/apis/numaflow/v1alpha1/get_spec_req.go @@ -45,10 +45,11 @@ type GetRedisServiceSpecReq struct { } type GetVertexPodSpecReq struct { - ISBSvcType ISBSvcType `protobuf:"bytes,1,opt,name=isbSvcType"` - Image string `protobuf:"bytes,2,opt,name=image"` - PullPolicy corev1.PullPolicy `protobuf:"bytes,3,opt,name=pullPolicy,casttype=k8s.io/api/core/v1.PullPolicy"` - Env []corev1.EnvVar `protobuf:"bytes,4,rep,name=env"` + ISBSvcType ISBSvcType `protobuf:"bytes,1,opt,name=isbSvcType"` + Image string `protobuf:"bytes,2,opt,name=image"` + PullPolicy corev1.PullPolicy `protobuf:"bytes,3,opt,name=pullPolicy,casttype=k8s.io/api/core/v1.PullPolicy"` + Env []corev1.EnvVar `protobuf:"bytes,4,rep,name=env"` + SideInputsStoreName string `protobuf:"bytes,5,opt,name=sideInputsStoreName"` } type GetDaemonDeploymentReq struct { @@ -82,3 +83,10 @@ type GetJetStreamServiceSpecReq struct { MonitorPort int32 `protobuf:"bytes,4,opt,name=monitorPort"` MetricsPort int32 `protobuf:"bytes,5,opt,name=metricsPort"` } + +type GetSideInputDeploymentReq struct { + ISBSvcType ISBSvcType `protobuf:"bytes,1,opt,name=isbSvcType"` + Image string `protobuf:"bytes,2,opt,name=image"` + PullPolicy corev1.PullPolicy `protobuf:"bytes,3,opt,name=pullPolicy,casttype=k8s.io/api/core/v1.PullPolicy"` + Env []corev1.EnvVar `protobuf:"bytes,4,rep,name=env"` +} diff --git a/pkg/apis/numaflow/v1alpha1/openapi_generated.go b/pkg/apis/numaflow/v1alpha1/openapi_generated.go index 8183c1245..76937262b 100644 --- a/pkg/apis/numaflow/v1alpha1/openapi_generated.go +++ b/pkg/apis/numaflow/v1alpha1/openapi_generated.go @@ -51,6 +51,7 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.GetJetStreamStatefulSetSpecReq": schema_pkg_apis_numaflow_v1alpha1_GetJetStreamStatefulSetSpecReq(ref), "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.GetRedisServiceSpecReq": schema_pkg_apis_numaflow_v1alpha1_GetRedisServiceSpecReq(ref), "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.GetRedisStatefulSetSpecReq": schema_pkg_apis_numaflow_v1alpha1_GetRedisStatefulSetSpecReq(ref), + "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.GetSideInputDeploymentReq": schema_pkg_apis_numaflow_v1alpha1_GetSideInputDeploymentReq(ref), "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.GetVertexPodSpecReq": schema_pkg_apis_numaflow_v1alpha1_GetVertexPodSpecReq(ref), "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.GroupBy": schema_pkg_apis_numaflow_v1alpha1_GroupBy(ref), "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.HTTPSource": schema_pkg_apis_numaflow_v1alpha1_HTTPSource(ref), @@ -83,6 +84,9 @@ func GetOpenAPIDefinitions(ref common.ReferenceCallback) map[string]common.OpenA "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SASL": schema_pkg_apis_numaflow_v1alpha1_SASL(ref), "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SASLPlain": schema_pkg_apis_numaflow_v1alpha1_SASLPlain(ref), "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Scale": schema_pkg_apis_numaflow_v1alpha1_Scale(ref), + "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SideInput": schema_pkg_apis_numaflow_v1alpha1_SideInput(ref), + "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SideInputTrigger": schema_pkg_apis_numaflow_v1alpha1_SideInputTrigger(ref), + "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SideInputsManagerTemplate": schema_pkg_apis_numaflow_v1alpha1_SideInputsManagerTemplate(ref), "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Sink": schema_pkg_apis_numaflow_v1alpha1_Sink(ref), "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SlidingWindow": schema_pkg_apis_numaflow_v1alpha1_SlidingWindow(ref), "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Source": schema_pkg_apis_numaflow_v1alpha1_Source(ref), @@ -268,12 +272,14 @@ func schema_pkg_apis_numaflow_v1alpha1_AbstractVertex(ref common.ReferenceCallba }, "containerTemplate": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate"), + Description: "Container template for the main numa container.", + Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate"), }, }, "initContainerTemplate": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate"), + Description: "Container template for all the vertex pod init containers spawned by numaflow, excluding the ones specified by the user.", + Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate"), }, }, "metadata": { @@ -426,7 +432,7 @@ func schema_pkg_apis_numaflow_v1alpha1_AbstractVertex(ref common.ReferenceCallba }, "initContainers": { SchemaProps: spec.SchemaProps{ - Description: "List of init containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", + Description: "List of customized init containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -440,7 +446,7 @@ func schema_pkg_apis_numaflow_v1alpha1_AbstractVertex(ref common.ReferenceCallba }, "sidecars": { SchemaProps: spec.SchemaProps{ - Description: "List of sidecar containers belonging to the pod.", + Description: "List of customized sidecar containers belonging to the pod.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -459,6 +465,27 @@ func schema_pkg_apis_numaflow_v1alpha1_AbstractVertex(ref common.ReferenceCallba Format: "int32", }, }, + "sideInputs": { + SchemaProps: spec.SchemaProps{ + Description: "Names of the side inputs used in this vertex.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "sideInputsContainerTemplate": { + SchemaProps: spec.SchemaProps{ + Description: "Container template for the side inputs watcher container.", + Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate"), + }, + }, }, Required: []string{"name"}, }, @@ -1575,7 +1602,7 @@ func schema_pkg_apis_numaflow_v1alpha1_GetRedisStatefulSetSpecReq(ref common.Ref } } -func schema_pkg_apis_numaflow_v1alpha1_GetVertexPodSpecReq(ref common.ReferenceCallback) common.OpenAPIDefinition { +func schema_pkg_apis_numaflow_v1alpha1_GetSideInputDeploymentReq(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ SchemaProps: spec.SchemaProps{ @@ -1624,6 +1651,62 @@ func schema_pkg_apis_numaflow_v1alpha1_GetVertexPodSpecReq(ref common.ReferenceC } } +func schema_pkg_apis_numaflow_v1alpha1_GetVertexPodSpecReq(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "ISBSvcType": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "Image": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "PullPolicy": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "Env": { + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.EnvVar"), + }, + }, + }, + }, + }, + "SideInputsStoreName": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + Required: []string{"ISBSvcType", "Image", "PullPolicy", "Env", "SideInputsStoreName"}, + }, + }, + Dependencies: []string{ + "k8s.io/api/core/v1.EnvVar"}, + } +} + func schema_pkg_apis_numaflow_v1alpha1_GroupBy(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -2838,14 +2921,14 @@ func schema_pkg_apis_numaflow_v1alpha1_PipelineLimits(ref common.ReferenceCallba Properties: map[string]spec.Schema{ "readBatchSize": { SchemaProps: spec.SchemaProps{ - Description: "Read batch size for all the vertices in the pipeline, can be overridden by the vertex's limit settings", + Description: "Read batch size for all the vertices in the pipeline, can be overridden by the vertex's limit settings.", Type: []string{"integer"}, Format: "int64", }, }, "bufferMaxLength": { SchemaProps: spec.SchemaProps{ - Description: "BufferMaxLength is used to define the max length of a buffer Only applies to UDF and Source vertices as only they do buffer write. It can be overridden by the settings in vertex limits.", + Description: "BufferMaxLength is used to define the max length of a buffer. Only applies to UDF and Source vertices as only they do buffer write. It can be overridden by the settings in vertex limits.", Type: []string{"integer"}, Format: "int64", }, @@ -2990,11 +3073,25 @@ func schema_pkg_apis_numaflow_v1alpha1_PipelineSpec(ref common.ReferenceCallback Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Templates"), }, }, + "sideInputs": { + SchemaProps: spec.SchemaProps{ + Description: "SideInputs defines the Side Inputs of a pipeline.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SideInput"), + }, + }, + }, + }, + }, }, }, }, Dependencies: []string{ - "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.AbstractVertex", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Edge", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Lifecycle", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.PipelineLimits", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Templates", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Watermark"}, + "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.AbstractVertex", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Edge", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Lifecycle", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.PipelineLimits", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SideInput", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Templates", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Watermark"}, } } @@ -3420,6 +3517,231 @@ func schema_pkg_apis_numaflow_v1alpha1_Scale(ref common.ReferenceCallback) commo } } +func schema_pkg_apis_numaflow_v1alpha1_SideInput(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Description: "SideInput defines information of a Side Input", + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "name": { + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + "container": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Container"), + }, + }, + "volumes": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.Volume"), + }, + }, + }, + }, + }, + "trigger": { + SchemaProps: spec.SchemaProps{ + Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SideInputTrigger"), + }, + }, + }, + Required: []string{"name", "container", "trigger"}, + }, + }, + Dependencies: []string{ + "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Container", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SideInputTrigger", "k8s.io/api/core/v1.Volume"}, + } +} + +func schema_pkg_apis_numaflow_v1alpha1_SideInputTrigger(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "schedule": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + "interval": { + SchemaProps: spec.SchemaProps{ + Ref: ref("k8s.io/apimachinery/pkg/apis/meta/v1.Duration"), + }, + }, + "timezone": { + SchemaProps: spec.SchemaProps{ + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + Dependencies: []string{ + "k8s.io/apimachinery/pkg/apis/meta/v1.Duration"}, + } +} + +func schema_pkg_apis_numaflow_v1alpha1_SideInputsManagerTemplate(ref common.ReferenceCallback) common.OpenAPIDefinition { + return common.OpenAPIDefinition{ + Schema: spec.Schema{ + SchemaProps: spec.SchemaProps{ + Type: []string{"object"}, + Properties: map[string]spec.Schema{ + "metadata": { + SchemaProps: spec.SchemaProps{ + Description: "Metadata sets the pods's metadata, i.e. annotations and labels", + Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Metadata"), + }, + }, + "nodeSelector": { + SchemaProps: spec.SchemaProps{ + Description: "NodeSelector is a selector which must be true for the pod to fit on a node. Selector which must match a node's labels for the pod to be scheduled on that node. More info: https://kubernetes.io/docs/concepts/configuration/assign-pod-node/", + Type: []string{"object"}, + AdditionalProperties: &spec.SchemaOrBool{ + Allows: true, + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "tolerations": { + SchemaProps: spec.SchemaProps{ + Description: "If specified, the pod's tolerations.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.Toleration"), + }, + }, + }, + }, + }, + "securityContext": { + SchemaProps: spec.SchemaProps{ + Description: "SecurityContext holds pod-level security attributes and common container settings. Optional: Defaults to empty. See type description for default values of each field.", + Ref: ref("k8s.io/api/core/v1.PodSecurityContext"), + }, + }, + "imagePullSecrets": { + VendorExtensible: spec.VendorExtensible{ + Extensions: spec.Extensions{ + "x-kubernetes-patch-merge-key": "name", + "x-kubernetes-patch-strategy": "merge", + }, + }, + SchemaProps: spec.SchemaProps{ + Description: "ImagePullSecrets is an optional list of references to secrets in the same namespace to use for pulling any of the images used by this PodSpec. If specified, these secrets will be passed to individual puller implementations for them to use. For example, in the case of docker, only DockerConfig type secrets are honored. More info: https://kubernetes.io/docs/concepts/containers/images#specifying-imagepullsecrets-on-a-pod", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: map[string]interface{}{}, + Ref: ref("k8s.io/api/core/v1.LocalObjectReference"), + }, + }, + }, + }, + }, + "priorityClassName": { + SchemaProps: spec.SchemaProps{ + Description: "If specified, indicates the Redis pod's priority. \"system-node-critical\" and \"system-cluster-critical\" are two special keywords which indicate the highest priorities with the former being the highest priority. Any other name must be defined by creating a PriorityClass object with that name. If not specified, the pod priority will be default or zero if there is no default. More info: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/", + Type: []string{"string"}, + Format: "", + }, + }, + "priority": { + SchemaProps: spec.SchemaProps{ + Description: "The priority value. Various system components use this field to find the priority of the Redis pod. When Priority Admission Controller is enabled, it prevents users from setting this field. The admission controller populates this field from PriorityClassName. The higher the value, the higher the priority. More info: https://kubernetes.io/docs/concepts/configuration/pod-priority-preemption/", + Type: []string{"integer"}, + Format: "int32", + }, + }, + "affinity": { + SchemaProps: spec.SchemaProps{ + Description: "The pod's scheduling constraints More info: https://kubernetes.io/docs/concepts/scheduling-eviction/assign-pod-node/", + Ref: ref("k8s.io/api/core/v1.Affinity"), + }, + }, + "serviceAccountName": { + SchemaProps: spec.SchemaProps{ + Description: "ServiceAccountName applied to the pod", + Type: []string{"string"}, + Format: "", + }, + }, + "runtimeClassName": { + SchemaProps: spec.SchemaProps{ + Description: "RuntimeClassName refers to a RuntimeClass object in the node.k8s.io group, which should be used to run this pod. If no RuntimeClass resource matches the named class, the pod will not be run. If unset or empty, the \"legacy\" RuntimeClass will be used, which is an implicit class with an empty definition that uses the default runtime handler. More info: https://git.k8s.io/enhancements/keps/sig-node/585-runtime-class", + Type: []string{"string"}, + Format: "", + }, + }, + "automountServiceAccountToken": { + SchemaProps: spec.SchemaProps{ + Description: "AutomountServiceAccountToken indicates whether a service account token should be automatically mounted.", + Type: []string{"boolean"}, + Format: "", + }, + }, + "dnsPolicy": { + SchemaProps: spec.SchemaProps{ + Description: "Set DNS policy for the pod. Defaults to \"ClusterFirst\". Valid values are 'ClusterFirstWithHostNet', 'ClusterFirst', 'Default' or 'None'. DNS parameters given in DNSConfig will be merged with the policy selected with DNSPolicy. To have DNS options set along with hostNetwork, you have to specify DNS policy explicitly to 'ClusterFirstWithHostNet'.", + Type: []string{"string"}, + Format: "", + }, + }, + "dnsConfig": { + SchemaProps: spec.SchemaProps{ + Description: "Specifies the DNS parameters of a pod. Parameters specified here will be merged to the generated DNS configuration based on DNSPolicy.", + Ref: ref("k8s.io/api/core/v1.PodDNSConfig"), + }, + }, + "containerTemplate": { + SchemaProps: spec.SchemaProps{ + Description: "Template for the side inputs manager numa container", + Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate"), + }, + }, + "initContainerTemplate": { + SchemaProps: spec.SchemaProps{ + Description: "Template for the side inputs manager init container", + Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate"), + }, + }, + }, + }, + }, + Dependencies: []string{ + "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.Metadata", "k8s.io/api/core/v1.Affinity", "k8s.io/api/core/v1.LocalObjectReference", "k8s.io/api/core/v1.PodDNSConfig", "k8s.io/api/core/v1.PodSecurityContext", "k8s.io/api/core/v1.Toleration"}, + } +} + func schema_pkg_apis_numaflow_v1alpha1_Sink(ref common.ReferenceCallback) common.OpenAPIDefinition { return common.OpenAPIDefinition{ Schema: spec.Schema{ @@ -3639,21 +3961,27 @@ func schema_pkg_apis_numaflow_v1alpha1_Templates(ref common.ReferenceCallback) c Properties: map[string]spec.Schema{ "daemon": { SchemaProps: spec.SchemaProps{ - Description: "DaemonTemplate is used to customize the Daemon Deployment", + Description: "DaemonTemplate is used to customize the Daemon Deployment.", Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.DaemonTemplate"), }, }, "job": { SchemaProps: spec.SchemaProps{ - Description: "JobTemplate is used to customize Jobs", + Description: "JobTemplate is used to customize Jobs.", Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.JobTemplate"), }, }, + "sideInputsManager": { + SchemaProps: spec.SchemaProps{ + Description: "SideInputsManagerTemplate is used to customize the Side Inputs Manager.", + Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SideInputsManagerTemplate"), + }, + }, }, }, }, Dependencies: []string{ - "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.DaemonTemplate", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.JobTemplate"}, + "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.DaemonTemplate", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.JobTemplate", "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.SideInputsManagerTemplate"}, } } @@ -3978,12 +4306,14 @@ func schema_pkg_apis_numaflow_v1alpha1_VertexSpec(ref common.ReferenceCallback) }, "containerTemplate": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate"), + Description: "Container template for the main numa container.", + Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate"), }, }, "initContainerTemplate": { SchemaProps: spec.SchemaProps{ - Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate"), + Description: "Container template for all the vertex pod init containers spawned by numaflow, excluding the ones specified by the user.", + Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate"), }, }, "metadata": { @@ -4136,7 +4466,7 @@ func schema_pkg_apis_numaflow_v1alpha1_VertexSpec(ref common.ReferenceCallback) }, "initContainers": { SchemaProps: spec.SchemaProps{ - Description: "List of init containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", + Description: "List of customized init containers belonging to the pod. More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -4150,7 +4480,7 @@ func schema_pkg_apis_numaflow_v1alpha1_VertexSpec(ref common.ReferenceCallback) }, "sidecars": { SchemaProps: spec.SchemaProps{ - Description: "List of sidecar containers belonging to the pod.", + Description: "List of customized sidecar containers belonging to the pod.", Type: []string{"array"}, Items: &spec.SchemaOrArray{ Schema: &spec.Schema{ @@ -4169,6 +4499,27 @@ func schema_pkg_apis_numaflow_v1alpha1_VertexSpec(ref common.ReferenceCallback) Format: "int32", }, }, + "sideInputs": { + SchemaProps: spec.SchemaProps{ + Description: "Names of the side inputs used in this vertex.", + Type: []string{"array"}, + Items: &spec.SchemaOrArray{ + Schema: &spec.Schema{ + SchemaProps: spec.SchemaProps{ + Default: "", + Type: []string{"string"}, + Format: "", + }, + }, + }, + }, + }, + "sideInputsContainerTemplate": { + SchemaProps: spec.SchemaProps{ + Description: "Container template for the side inputs watcher container.", + Ref: ref("github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1.ContainerTemplate"), + }, + }, "pipelineName": { SchemaProps: spec.SchemaProps{ Default: "", diff --git a/pkg/apis/numaflow/v1alpha1/pipeline_types.go b/pkg/apis/numaflow/v1alpha1/pipeline_types.go index 393f52d8f..f59c4ff72 100644 --- a/pkg/apis/numaflow/v1alpha1/pipeline_types.go +++ b/pkg/apis/numaflow/v1alpha1/pipeline_types.go @@ -175,6 +175,11 @@ func (p Pipeline) GetDownstreamEdges(vertexName string) []Edge { return result } +// HasSideInputs returns if the pipeline has side inputs. +func (p Pipeline) HasSideInputs() bool { + return len(p.Spec.SideInputs) > 0 +} + func (p Pipeline) GetDaemonServiceName() string { return fmt.Sprintf("%s-daemon-svc", p.Name) } @@ -182,10 +187,40 @@ func (p Pipeline) GetDaemonServiceName() string { func (p Pipeline) GetDaemonDeploymentName() string { return fmt.Sprintf("%s-daemon", p.Name) } + func (p Pipeline) GetDaemonServiceURL() string { return fmt.Sprintf("%s.%s.svc:%d", p.GetDaemonServiceName(), p.Namespace, DaemonServicePort) } +func (p Pipeline) GetSideInputsManagerDeploymentName(sideInputName string) string { + return fmt.Sprintf("%s-si-%s", p.Name, sideInputName) +} + +func (p Pipeline) GetSideInputsStoreName() string { + return fmt.Sprintf("%s-%s", p.Namespace, p.Name) +} + +func (p Pipeline) GetSideInputsManagerDeployments(req GetSideInputDeploymentReq) ([]*appv1.Deployment, error) { + commonEnvVars := []corev1.EnvVar{ + {Name: EnvNamespace, ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{FieldPath: "metadata.namespace"}}}, + {Name: EnvPod, ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{FieldPath: "metadata.name"}}}, + } + deployments := []*appv1.Deployment{} + for _, sideInput := range p.Spec.SideInputs { + deployment, err := sideInput.getManagerDeploymentObj(p, req) + if err != nil { + return nil, err + } + for i := 0; i < len(deployment.Spec.Template.Spec.Containers); i++ { + deployment.Spec.Template.Spec.Containers[i].Env = append(deployment.Spec.Template.Spec.Containers[i].Env, commonEnvVars...) + } + deployment.Spec.Template.Spec.InitContainers[0].Env = append(deployment.Spec.Template.Spec.InitContainers[0].Env, corev1.EnvVar{Name: EnvGoDebug, Value: os.Getenv(EnvGoDebug)}) + deployment.Spec.Template.Spec.Containers[0].Env = append(deployment.Spec.Template.Spec.Containers[0].Env, corev1.EnvVar{Name: EnvGoDebug, Value: os.Getenv(EnvGoDebug)}) + deployments = append(deployments, deployment) + } + return deployments, nil +} + func (p Pipeline) GetDaemonDeploymentObj(req GetDaemonDeploymentReq) (*appv1.Deployment, error) { pipelineCopy := &Pipeline{ ObjectMeta: metav1.ObjectMeta{ @@ -204,7 +239,7 @@ func (p Pipeline) GetDaemonDeploymentObj(req GetDaemonDeploymentReq) (*appv1.Dep {Name: EnvNamespace, ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{FieldPath: "metadata.namespace"}}}, {Name: EnvPod, ValueFrom: &corev1.EnvVarSource{FieldRef: &corev1.ObjectFieldSelector{FieldPath: "metadata.name"}}}, {Name: EnvPipelineObject, Value: encodedPipeline}, - {Name: "GODEBUG", Value: os.Getenv("GODEBUG")}, + {Name: EnvGoDebug, Value: os.Getenv(EnvGoDebug)}, } envVars = append(envVars, req.Env...) c := corev1.Container{ @@ -286,7 +321,7 @@ func (p Pipeline) GetDaemonDeploymentObj(req GetDaemonDeploymentReq) (*appv1.Dep func (p Pipeline) getDaemonPodInitContainer(req GetDaemonDeploymentReq) corev1.Container { envVars := []corev1.EnvVar{ - {Name: "GODEBUG", Value: os.Getenv("GODEBUG")}, + {Name: EnvGoDebug, Value: os.Getenv(EnvGoDebug)}, } envVars = append(envVars, req.Env...) c := corev1.Container{ @@ -408,6 +443,9 @@ type PipelineSpec struct { // Templates is used to customize additional kubernetes resources required for the Pipeline // +optional Templates *Templates `json:"templates,omitempty" protobuf:"bytes,7,opt,name=templates"` + // SideInputs defines the Side Inputs of a pipeline. + // +optional + SideInputs []SideInput `json:"sideInputs,omitempty" protobuf:"bytes,8,rep,name=sideInputs"` } type Watermark struct { @@ -421,7 +459,7 @@ type Watermark struct { MaxDelay *metav1.Duration `json:"maxDelay,omitempty" protobuf:"bytes,2,opt,name=maxDelay"` } -// GetMaxDelay returns the configured max delay with a default value +// GetMaxDelay returns the configured max delay with a default value. func (wm Watermark) GetMaxDelay() time.Duration { if wm.MaxDelay != nil { return wm.MaxDelay.Duration @@ -430,20 +468,23 @@ func (wm Watermark) GetMaxDelay() time.Duration { } type Templates struct { - // DaemonTemplate is used to customize the Daemon Deployment + // DaemonTemplate is used to customize the Daemon Deployment. // +optional DaemonTemplate *DaemonTemplate `json:"daemon,omitempty" protobuf:"bytes,1,opt,name=daemon"` - // JobTemplate is used to customize Jobs + // JobTemplate is used to customize Jobs. // +optional JobTemplate *JobTemplate `json:"job,omitempty" protobuf:"bytes,2,opt,name=job"` + // SideInputsManagerTemplate is used to customize the Side Inputs Manager. + // +optional + SideInputsManagerTemplate *SideInputsManagerTemplate `json:"sideInputsManager,omitempty" protobuf:"bytes,3,opt,name=sideInputsManager"` } type PipelineLimits struct { - // Read batch size for all the vertices in the pipeline, can be overridden by the vertex's limit settings + // Read batch size for all the vertices in the pipeline, can be overridden by the vertex's limit settings. // +kubebuilder:default=500 // +optional ReadBatchSize *uint64 `json:"readBatchSize,omitempty" protobuf:"varint,1,opt,name=readBatchSize"` - // BufferMaxLength is used to define the max length of a buffer + // BufferMaxLength is used to define the max length of a buffer. // Only applies to UDF and Source vertices as only they do buffer write. // It can be overridden by the settings in vertex limits. // +kubebuilder:default=30000 diff --git a/pkg/apis/numaflow/v1alpha1/pipeline_types_test.go b/pkg/apis/numaflow/v1alpha1/pipeline_types_test.go index a665d8246..f916e74b6 100644 --- a/pkg/apis/numaflow/v1alpha1/pipeline_types_test.go +++ b/pkg/apis/numaflow/v1alpha1/pipeline_types_test.go @@ -394,3 +394,30 @@ func Test_FindVertexWithBuffer(t *testing.T) { v := testPipeline.FindVertexWithBuffer(GenerateBufferName(testNamespace, testPipelineName, "p1", 0)) assert.NotNil(t, v) } + +func Test_GetSideInputManagerDeployments(t *testing.T) { + t.Run("side inputs not enabled", func(t *testing.T) { + deployments, err := testPipeline.GetSideInputsManagerDeployments(testGetSideInputDeploymentReq) + assert.Nil(t, err) + assert.Equal(t, 0, len(deployments)) + }) + + t.Run("side inputs enabled", func(t *testing.T) { + testObj := testPipeline.DeepCopy() + testObj.Spec.SideInputs = []SideInput{ + { + Name: "side-input-1", + Container: &Container{ + Image: "side-input-1", + }, + Trigger: &SideInputTrigger{ + Schedule: pointer.String("0 0 * * *"), + }, + }, + } + deployments, err := testObj.GetSideInputsManagerDeployments(testGetSideInputDeploymentReq) + assert.Nil(t, err) + assert.Equal(t, 1, len(deployments)) + assert.Equal(t, 2, len(deployments[0].Spec.Template.Spec.Containers)) + }) +} diff --git a/pkg/apis/numaflow/v1alpha1/side_inputs.go b/pkg/apis/numaflow/v1alpha1/side_inputs.go new file mode 100644 index 000000000..33115cadd --- /dev/null +++ b/pkg/apis/numaflow/v1alpha1/side_inputs.go @@ -0,0 +1,184 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "encoding/base64" + "encoding/json" + "fmt" + + appv1 "k8s.io/api/apps/v1" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// SideInput defines information of a Side Input +type SideInput struct { + Name string `json:"name" protobuf:"bytes,1,opt,name=name"` + Container *Container `json:"container" protobuf:"bytes,2,opt,name=container"` + // +optional + // +patchStrategy=merge + // +patchMergeKey=name + Volumes []corev1.Volume `json:"volumes,omitempty" patchStrategy:"merge" patchMergeKey:"name" protobuf:"bytes,3,rep,name=volumes"` + Trigger *SideInputTrigger `json:"trigger" protobuf:"bytes,4,opt,name=trigger"` +} + +type SideInputTrigger struct { + // +optional + Schedule *string `json:"schedule" protobuf:"bytes,1,opt,name=schedule"` + // +optional + Interval *metav1.Duration `json:"interval" protobuf:"bytes,2,opt,name=interval"` + // +optional + Timezone *string `json:"timezone" protobuf:"bytes,3,opt,name=timezone"` +} + +func (si SideInput) getManagerDeploymentObj(pipeline Pipeline, req GetSideInputDeploymentReq) (*appv1.Deployment, error) { + numaContainer, err := si.getNumaContainer(pipeline, req) + if err != nil { + return nil, err + } + labels := map[string]string{ + KeyPartOf: Project, + KeyManagedBy: ControllerPipeline, + KeyComponent: ComponentSideInputManager, + KeyPipelineName: pipeline.Name, + KeySideInputName: si.Name, + } + varVolumeName := "var-run-numaflow" + volumes := []corev1.Volume{ + { + Name: varVolumeName, + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{ + Medium: corev1.StorageMediumMemory, + }}, + }, + } + if len(si.Volumes) > 0 { + volumes = append(volumes, si.Volumes...) + } + volumeMounts := []corev1.VolumeMount{{Name: varVolumeName, MountPath: PathVarRun}} + deployment := &appv1.Deployment{ + ObjectMeta: metav1.ObjectMeta{ + Name: pipeline.GetSideInputsManagerDeploymentName(si.Name), + Namespace: pipeline.Namespace, + Labels: labels, + OwnerReferences: []metav1.OwnerReference{ + *metav1.NewControllerRef(pipeline.GetObjectMeta(), PipelineGroupVersionKind), + }, + }, + Spec: appv1.DeploymentSpec{ + Selector: &metav1.LabelSelector{ + MatchLabels: labels, + }, + Template: corev1.PodTemplateSpec{ + ObjectMeta: metav1.ObjectMeta{ + Labels: labels, + Annotations: map[string]string{ + KeyDefaultContainer: CtrUdSideInput, + }, + }, + Spec: corev1.PodSpec{ + Containers: []corev1.Container{*numaContainer, si.getUDContainer(req)}, + InitContainers: []corev1.Container{si.getInitContainer(pipeline, req)}, + Volumes: volumes, + }, + }, + }, + } + if x := pipeline.Spec.Templates; x != nil && x.SideInputsManagerTemplate != nil { + x.SideInputsManagerTemplate.ApplyToPodTemplateSpec(&deployment.Spec.Template) + } + for i := range deployment.Spec.Template.Spec.Containers { + deployment.Spec.Template.Spec.Containers[i].VolumeMounts = append(deployment.Spec.Template.Spec.Containers[i].VolumeMounts, volumeMounts...) + } + return deployment, nil +} + +func (si SideInput) getInitContainer(pipeline Pipeline, req GetSideInputDeploymentReq) corev1.Container { + c := corev1.Container{ + Name: CtrInit, + Env: req.Env, + Image: req.Image, + ImagePullPolicy: req.PullPolicy, + Resources: standardResources, + Args: []string{"isbsvc-validate", "--isbsvc-type=" + string(req.ISBSvcType)}, + } + c.Args = append(c.Args, "--side-inputs-store="+pipeline.GetSideInputsStoreName()) + if x := pipeline.Spec.Templates; x != nil && x.SideInputsManagerTemplate != nil && x.SideInputsManagerTemplate.InitContainerTemplate != nil { + x.SideInputsManagerTemplate.InitContainerTemplate.ApplyToContainer(&c) + } + return c +} + +func (si SideInput) getNumaContainer(pipeline Pipeline, req GetSideInputDeploymentReq) (*corev1.Container, error) { + sideInputCopy := &SideInput{ + Name: si.Name, + Trigger: si.Trigger, + } + siBytes, err := json.Marshal(sideInputCopy) + if err != nil { + return nil, fmt.Errorf("failed to marshal SideInput spec") + } + encodedSideInput := base64.StdEncoding.EncodeToString(siBytes) + envVars := []corev1.EnvVar{ + {Name: EnvSideInputObject, Value: encodedSideInput}, + } + envVars = append(envVars, req.Env...) + c := &corev1.Container{ + Name: CtrMain, + Env: envVars, + Image: req.Image, + ImagePullPolicy: req.PullPolicy, + Resources: standardResources, + Args: []string{"side-inputs-manager", "--isbsvc-type=" + string(req.ISBSvcType), "--side-inputs-store=" + pipeline.GetSideInputsStoreName()}, + } + if x := pipeline.Spec.Templates; x != nil && x.SideInputsManagerTemplate != nil && x.SideInputsManagerTemplate.ContainerTemplate != nil { + x.SideInputsManagerTemplate.ContainerTemplate.ApplyToContainer(c) + } + return c, nil +} + +func (si SideInput) getUDContainer(req GetSideInputDeploymentReq) corev1.Container { + cb := containerBuilder{}. + name(CtrUdSideInput). + image(si.Container.Image). + imagePullPolicy(req.PullPolicy) + if si.Container.ImagePullPolicy != nil { + cb = cb.imagePullPolicy(*si.Container.ImagePullPolicy) + } + if len(si.Container.Command) > 0 { + cb = cb.command(si.Container.Command...) + } + if len(si.Container.Args) > 0 { + cb = cb.args(si.Container.Args...) + } + // Do not append the envs from req here, as they might contain sensitive information + cb = cb.appendEnv(si.Container.Env...).appendVolumeMounts(si.Container.VolumeMounts...). + resources(si.Container.Resources).securityContext(si.Container.SecurityContext).appendEnvFrom(si.Container.EnvFrom...) + return cb.build() +} + +type SideInputsManagerTemplate struct { + // +optional + AbstractPodTemplate `json:",inline" protobuf:"bytes,1,opt,name=abstractPodTemplate"` + // Template for the side inputs manager numa container + // +optional + ContainerTemplate *ContainerTemplate `json:"containerTemplate,omitempty" protobuf:"bytes,2,opt,name=containerTemplate"` + // Template for the side inputs manager init container + // +optional + InitContainerTemplate *ContainerTemplate `json:"initContainerTemplate,omitempty" protobuf:"bytes,3,opt,name=initContainerTemplate"` +} diff --git a/pkg/apis/numaflow/v1alpha1/side_inputs_test.go b/pkg/apis/numaflow/v1alpha1/side_inputs_test.go new file mode 100644 index 000000000..dbe72594c --- /dev/null +++ b/pkg/apis/numaflow/v1alpha1/side_inputs_test.go @@ -0,0 +1,102 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package v1alpha1 + +import ( + "testing" + "time" + + "github.com/stretchr/testify/assert" + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +var ( + imagePullNever = corev1.PullNever + testSideInput = &SideInput{ + Name: "test-side-input", + Container: &Container{ + Image: "test-image", + Env: []corev1.EnvVar{ + {Name: "key1", Value: "value1"}, + }, + Command: []string{"test-command"}, + Args: []string{"test-args"}, + ImagePullPolicy: &imagePullNever, + }, + Trigger: &SideInputTrigger{ + Interval: &metav1.Duration{Duration: time.Duration(1 * time.Second)}, + }, + } + + testGetSideInputDeploymentReq = GetSideInputDeploymentReq{ + ISBSvcType: ISBSvcTypeJetStream, + Image: "test-image", + PullPolicy: corev1.PullAlways, + Env: []corev1.EnvVar{ + {Name: "key2", Value: "value2"}, + }, + } +) + +func Test_getUDContainer(t *testing.T) { + c := testSideInput.getUDContainer(testGetSideInputDeploymentReq) + assert.Equal(t, CtrUdSideInput, c.Name) + assert.Equal(t, testSideInput.Container.Image, c.Image) + assert.Equal(t, testSideInput.Container.Command, c.Command) + for _, env := range testSideInput.Container.Env { + assert.Contains(t, c.Env, env) + } + assert.Equal(t, imagePullNever, c.ImagePullPolicy) +} + +func Test_getNumaContainer(t *testing.T) { + c, err := testSideInput.getNumaContainer(*testPipeline, testGetSideInputDeploymentReq) + assert.NoError(t, err) + assert.Equal(t, testSideInput.Container.Image, testGetSideInputDeploymentReq.Image) + for _, env := range testGetSideInputDeploymentReq.Env { + assert.Contains(t, c.Env, env) + } + assert.Equal(t, testGetSideInputDeploymentReq.PullPolicy, c.ImagePullPolicy) + assert.Equal(t, CtrMain, c.Name) +} + +func Test_getInitContainer(t *testing.T) { + c := testSideInput.getInitContainer(*testPipeline, testGetSideInputDeploymentReq) + assert.Equal(t, testSideInput.Container.Image, testGetSideInputDeploymentReq.Image) + for _, env := range testGetSideInputDeploymentReq.Env { + assert.Contains(t, c.Env, env) + } + assert.Equal(t, testGetSideInputDeploymentReq.PullPolicy, c.ImagePullPolicy) + assert.Equal(t, CtrInit, c.Name) +} + +func Test_getManagerDeploymentObj(t *testing.T) { + newObj := testSideInput.DeepCopy() + newObj.Volumes = []corev1.Volume{ + { + Name: "test-vol", + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}, + }, + } + deploy, err := newObj.getManagerDeploymentObj(*testPipeline, testGetSideInputDeploymentReq) + assert.NoError(t, err) + assert.NotNil(t, deploy) + assert.Equal(t, 1, len(deploy.Spec.Template.Spec.InitContainers)) + assert.Equal(t, 2, len(deploy.Spec.Template.Spec.Containers)) + assert.Equal(t, 2, len(deploy.Spec.Template.Spec.Volumes)) +} diff --git a/pkg/apis/numaflow/v1alpha1/vertex_types.go b/pkg/apis/numaflow/v1alpha1/vertex_types.go index 343c12cec..d4a9e327a 100644 --- a/pkg/apis/numaflow/v1alpha1/vertex_types.go +++ b/pkg/apis/numaflow/v1alpha1/vertex_types.go @@ -21,6 +21,7 @@ import ( "fmt" "os" "strconv" + "strings" corev1 "k8s.io/api/core/v1" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" @@ -76,6 +77,10 @@ func (v Vertex) HasUDTransformer() bool { return v.Spec.HasUDTransformer() } +func (v Vertex) HasSideInputs() bool { + return len(v.Spec.SideInputs) > 0 +} + func (v Vertex) IsASink() bool { return v.Spec.IsASink() } @@ -259,10 +264,44 @@ func (v Vertex) GetPodSpec(req GetVertexPodSpecReq) (*corev1.PodSpec, error) { } } + initContainers := v.getInitContainers(req) + + if v.HasSideInputs() { + sideInputsVolName := "var-run-side-inputs" + volumes = append(volumes, corev1.Volume{ + Name: sideInputsVolName, + VolumeSource: corev1.VolumeSource{EmptyDir: &corev1.EmptyDirVolumeSource{}}, + }) + + sideInputsWatcher := corev1.Container{ + Name: CtrSideInputsWatcher, + Env: req.Env, + Image: req.Image, + ImagePullPolicy: req.PullPolicy, + Resources: standardResources, + Args: []string{"side-inputs-watcher", "--isbsvc-type=" + string(req.ISBSvcType), "--side-inputs-store=" + req.SideInputsStoreName, "--side-inputs=" + strings.Join(v.Spec.SideInputs, ",")}, + } + sideInputsWatcher.Env = append(sideInputsWatcher.Env, v.commonEnvs()...) + if x := v.Spec.SideInputsContainerTemplate; x != nil { + x.ApplyToContainer(&sideInputsWatcher) + } + containers = append(containers, sideInputsWatcher) + for i := 1; i < len(containers); i++ { + if containers[i].Name == CtrSideInputsWatcher { + containers[i].VolumeMounts = append(containers[i].VolumeMounts, corev1.VolumeMount{Name: sideInputsVolName, MountPath: PathSideInputsMount}) + } else { + // Readonly mount for user defined containers + containers[i].VolumeMounts = append(containers[i].VolumeMounts, corev1.VolumeMount{Name: sideInputsVolName, MountPath: PathSideInputsMount, ReadOnly: true}) + } + } + // Side Inputs init container + initContainers[1].VolumeMounts = append(initContainers[1].VolumeMounts, corev1.VolumeMount{Name: sideInputsVolName, MountPath: PathSideInputsMount}) + } + spec := &corev1.PodSpec{ Subdomain: v.GetHeadlessServiceName(), Volumes: append(volumes, v.Spec.Volumes...), - InitContainers: v.getInitContainers(req), + InitContainers: initContainers, Containers: append(containers, v.Spec.Sidecars...), } v.Spec.AbstractPodTemplate.ApplyToPodSpec(spec) @@ -275,7 +314,7 @@ func (v Vertex) GetPodSpec(req GetVertexPodSpecReq) (*corev1.PodSpec, error) { func (v Vertex) getInitContainers(req GetVertexPodSpecReq) []corev1.Container { envVars := []corev1.EnvVar{ {Name: EnvPipelineName, Value: v.Spec.PipelineName}, - {Name: "GODEBUG", Value: os.Getenv("GODEBUG")}, + {Name: EnvGoDebug, Value: os.Getenv(EnvGoDebug)}, } envVars = append(envVars, req.Env...) initContainers := []corev1.Container{ @@ -288,6 +327,17 @@ func (v Vertex) getInitContainers(req GetVertexPodSpecReq) []corev1.Container { Args: []string{"isbsvc-validate", "--isbsvc-type=" + string(req.ISBSvcType)}, }, } + if v.HasSideInputs() { + initContainers = append(initContainers, corev1.Container{ + Name: CtrInitSideInputs, + Env: envVars, + Image: req.Image, + ImagePullPolicy: req.PullPolicy, + Resources: standardResources, + Args: []string{"side-inputs-init", "--isbsvc-type=" + string(req.ISBSvcType), "--side-inputs-store=" + req.SideInputsStoreName, "--side-inputs=" + strings.Join(v.Spec.SideInputs, ",")}, + }) + } + if v.Spec.InitContainerTemplate != nil { v.Spec.InitContainerTemplate.ApplyToNumaflowContainers(initContainers) } @@ -386,13 +436,15 @@ type VertexSpec struct { type AbstractVertex struct { Name string `json:"name" protobuf:"bytes,1,opt,name=name"` // +optional - Source *Source `json:"source,omitempty" protobuf:"bytes,2,rep,name=source"` + Source *Source `json:"source,omitempty" protobuf:"bytes,2,opt,name=source"` // +optional - Sink *Sink `json:"sink,omitempty" protobuf:"bytes,3,rep,name=sink"` + Sink *Sink `json:"sink,omitempty" protobuf:"bytes,3,opt,name=sink"` // +optional - UDF *UDF `json:"udf,omitempty" protobuf:"bytes,4,rep,name=udf"` + UDF *UDF `json:"udf,omitempty" protobuf:"bytes,4,opt,name=udf"` + // Container template for the main numa container. // +optional - ContainerTemplate *ContainerTemplate `json:"containerTemplate,omitempty" protobuf:"bytes,5,rep,name=containerTemplate"` + ContainerTemplate *ContainerTemplate `json:"containerTemplate,omitempty" protobuf:"bytes,5,opt,name=containerTemplate"` + // Container template for all the vertex pod init containers spawned by numaflow, excluding the ones specified by the user. // +optional InitContainerTemplate *ContainerTemplate `json:"initContainerTemplate,omitempty" protobuf:"bytes,6,opt,name=initContainerTemplate"` // +optional @@ -407,17 +459,23 @@ type AbstractVertex struct { // Settings for autoscaling // +optional Scale Scale `json:"scale,omitempty" protobuf:"bytes,10,opt,name=scale"` - // List of init containers belonging to the pod. + // List of customized init containers belonging to the pod. // More info: https://kubernetes.io/docs/concepts/workloads/pods/init-containers/ // +optional InitContainers []corev1.Container `json:"initContainers,omitempty" protobuf:"bytes,11,rep,name=initContainers"` - // List of sidecar containers belonging to the pod. + // List of customized sidecar containers belonging to the pod. // +optional Sidecars []corev1.Container `json:"sidecars,omitempty" protobuf:"bytes,12,rep,name=sidecars"` // Number of partitions of the vertex owned buffers. // It applies to udf and sink vertices only. // +optional - Partitions *int32 `json:"partitions,omitempty" protobuf:"bytes,13,rep,name=partitions"` + Partitions *int32 `json:"partitions,omitempty" protobuf:"bytes,13,opt,name=partitions"` + // Names of the side inputs used in this vertex. + // +optional + SideInputs []string `json:"sideInputs,omitempty" protobuf:"bytes,14,rep,name=sideInputs"` + // Container template for the side inputs watcher container. + // +optional + SideInputsContainerTemplate *ContainerTemplate `json:"sideInputsContainerTemplate,omitempty" protobuf:"bytes,15,opt,name=sideInputsContainerTemplate"` } func (av AbstractVertex) GetVertexType() VertexType { diff --git a/pkg/apis/numaflow/v1alpha1/vertex_types_test.go b/pkg/apis/numaflow/v1alpha1/vertex_types_test.go index 41498b80c..430cc1cbd 100644 --- a/pkg/apis/numaflow/v1alpha1/vertex_types_test.go +++ b/pkg/apis/numaflow/v1alpha1/vertex_types_test.go @@ -196,6 +196,7 @@ func TestGetPodSpec(t *testing.T) { Env: []corev1.EnvVar{ {Name: "test-env", Value: "test-val"}, }, + SideInputsStoreName: "test-store", } t.Run("test source", func(t *testing.T) { testObj := testVertex.DeepCopy() @@ -353,6 +354,25 @@ func TestGetPodSpec(t *testing.T) { assert.Contains(t, sidecarEnvNames, EnvCPURequest) assert.Contains(t, sidecarEnvNames, EnvMemoryRequest) }) + + t.Run("test udf with side inputs", func(t *testing.T) { + testObj := testVertex.DeepCopy() + testObj.Spec.SideInputs = []string{"input1", "input2"} + testObj.Spec.UDF = &UDF{ + Builtin: &Function{ + Name: "cat", + }, + } + s, err := testObj.GetPodSpec(req) + assert.NoError(t, err) + assert.Equal(t, 3, len(s.Containers)) + assert.Equal(t, CtrMain, s.Containers[0].Name) + assert.Equal(t, CtrUdf, s.Containers[1].Name) + assert.Equal(t, CtrSideInputsWatcher, s.Containers[2].Name) + assert.Equal(t, 2, len(s.InitContainers)) + assert.Equal(t, CtrInit, s.InitContainers[0].Name) + assert.Equal(t, CtrInitSideInputs, s.InitContainers[1].Name) + }) } func Test_getType(t *testing.T) { diff --git a/pkg/apis/numaflow/v1alpha1/zz_generated.deepcopy.go b/pkg/apis/numaflow/v1alpha1/zz_generated.deepcopy.go index c0078c501..653418c42 100644 --- a/pkg/apis/numaflow/v1alpha1/zz_generated.deepcopy.go +++ b/pkg/apis/numaflow/v1alpha1/zz_generated.deepcopy.go @@ -158,6 +158,16 @@ func (in *AbstractVertex) DeepCopyInto(out *AbstractVertex) { *out = new(int32) **out = **in } + if in.SideInputs != nil { + in, out := &in.SideInputs, &out.SideInputs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.SideInputsContainerTemplate != nil { + in, out := &in.SideInputsContainerTemplate, &out.SideInputsContainerTemplate + *out = new(ContainerTemplate) + (*in).DeepCopyInto(*out) + } return } @@ -716,6 +726,29 @@ func (in *GetRedisStatefulSetSpecReq) DeepCopy() *GetRedisStatefulSetSpecReq { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *GetSideInputDeploymentReq) DeepCopyInto(out *GetSideInputDeploymentReq) { + *out = *in + if in.Env != nil { + in, out := &in.Env, &out.Env + *out = make([]v1.EnvVar, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new GetSideInputDeploymentReq. +func (in *GetSideInputDeploymentReq) DeepCopy() *GetSideInputDeploymentReq { + if in == nil { + return nil + } + out := new(GetSideInputDeploymentReq) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *GetVertexPodSpecReq) DeepCopyInto(out *GetVertexPodSpecReq) { *out = *in @@ -1423,6 +1456,13 @@ func (in *PipelineSpec) DeepCopyInto(out *PipelineSpec) { *out = new(Templates) (*in).DeepCopyInto(*out) } + if in.SideInputs != nil { + in, out := &in.SideInputs, &out.SideInputs + *out = make([]SideInput, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } return } @@ -1677,6 +1717,97 @@ func (in *Scale) DeepCopy() *Scale { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SideInput) DeepCopyInto(out *SideInput) { + *out = *in + if in.Container != nil { + in, out := &in.Container, &out.Container + *out = new(Container) + (*in).DeepCopyInto(*out) + } + if in.Volumes != nil { + in, out := &in.Volumes, &out.Volumes + *out = make([]v1.Volume, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } + if in.Trigger != nil { + in, out := &in.Trigger, &out.Trigger + *out = new(SideInputTrigger) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SideInput. +func (in *SideInput) DeepCopy() *SideInput { + if in == nil { + return nil + } + out := new(SideInput) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SideInputTrigger) DeepCopyInto(out *SideInputTrigger) { + *out = *in + if in.Schedule != nil { + in, out := &in.Schedule, &out.Schedule + *out = new(string) + **out = **in + } + if in.Interval != nil { + in, out := &in.Interval, &out.Interval + *out = new(metav1.Duration) + **out = **in + } + if in.Timezone != nil { + in, out := &in.Timezone, &out.Timezone + *out = new(string) + **out = **in + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SideInputTrigger. +func (in *SideInputTrigger) DeepCopy() *SideInputTrigger { + if in == nil { + return nil + } + out := new(SideInputTrigger) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *SideInputsManagerTemplate) DeepCopyInto(out *SideInputsManagerTemplate) { + *out = *in + in.AbstractPodTemplate.DeepCopyInto(&out.AbstractPodTemplate) + if in.ContainerTemplate != nil { + in, out := &in.ContainerTemplate, &out.ContainerTemplate + *out = new(ContainerTemplate) + (*in).DeepCopyInto(*out) + } + if in.InitContainerTemplate != nil { + in, out := &in.InitContainerTemplate, &out.InitContainerTemplate + *out = new(ContainerTemplate) + (*in).DeepCopyInto(*out) + } + return +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new SideInputsManagerTemplate. +func (in *SideInputsManagerTemplate) DeepCopy() *SideInputsManagerTemplate { + if in == nil { + return nil + } + out := new(SideInputsManagerTemplate) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *Sink) DeepCopyInto(out *Sink) { *out = *in @@ -1878,6 +2009,11 @@ func (in *Templates) DeepCopyInto(out *Templates) { *out = new(JobTemplate) (*in).DeepCopyInto(*out) } + if in.SideInputsManagerTemplate != nil { + in, out := &in.SideInputsManagerTemplate, &out.SideInputsManagerTemplate + *out = new(SideInputsManagerTemplate) + (*in).DeepCopyInto(*out) + } return } diff --git a/pkg/daemon/server/service/pipeline_metrics_query_test.go b/pkg/daemon/server/service/pipeline_metrics_query_test.go index 6fcbf3e2b..a45ea1b8b 100644 --- a/pkg/daemon/server/service/pipeline_metrics_query_test.go +++ b/pkg/daemon/server/service/pipeline_metrics_query_test.go @@ -55,15 +55,15 @@ func (ms *mockIsbSvcClient) GetBufferInfo(ctx context.Context, buffer string) (* }, nil } -func (ms *mockIsbSvcClient) CreateBuffersAndBuckets(ctx context.Context, buffers, buckets []string, opts ...isbsvc.CreateOption) error { +func (ms *mockIsbSvcClient) CreateBuffersAndBuckets(ctx context.Context, buffers, buckets []string, sideInputsStore string, opts ...isbsvc.CreateOption) error { return nil } -func (ms *mockIsbSvcClient) DeleteBuffersAndBuckets(ctx context.Context, buffers, buckets []string) error { +func (ms *mockIsbSvcClient) DeleteBuffersAndBuckets(ctx context.Context, buffers, buckets []string, sideInputsStore string) error { return nil } -func (ms *mockIsbSvcClient) ValidateBuffersAndBuckets(ctx context.Context, buffers, buckets []string) error { +func (ms *mockIsbSvcClient) ValidateBuffersAndBuckets(ctx context.Context, buffers, buckets []string, sideInputsStore string) error { return nil } diff --git a/pkg/daemon/server/service/rater/pod_tracker_test.go b/pkg/daemon/server/service/rater/pod_tracker_test.go index bf63d13ac..d50921318 100644 --- a/pkg/daemon/server/service/rater/pod_tracker_test.go +++ b/pkg/daemon/server/service/rater/pod_tracker_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package server import ( diff --git a/pkg/isbsvc/interface.go b/pkg/isbsvc/interface.go index 6ea26f182..19d140fa8 100644 --- a/pkg/isbsvc/interface.go +++ b/pkg/isbsvc/interface.go @@ -24,9 +24,9 @@ import ( // ISBService is an interface used to do the operations on ISBSvc type ISBService interface { - CreateBuffersAndBuckets(ctx context.Context, buffers, buckets []string, opts ...CreateOption) error - DeleteBuffersAndBuckets(ctx context.Context, buffers, buckets []string) error - ValidateBuffersAndBuckets(ctx context.Context, buffers, buckets []string) error + CreateBuffersAndBuckets(ctx context.Context, buffers, buckets []string, sideInputsStore string, opts ...CreateOption) error + DeleteBuffersAndBuckets(ctx context.Context, buffers, buckets []string, sideInputsStore string) error + ValidateBuffersAndBuckets(ctx context.Context, buffers, buckets []string, sideInputsStore string) error GetBufferInfo(ctx context.Context, buffer string) (*BufferInfo, error) CreateWatermarkFetcher(ctx context.Context, bucketName string, partitions int, isReduce bool) ([]fetch.Fetcher, error) } diff --git a/pkg/isbsvc/jetstream_service.go b/pkg/isbsvc/jetstream_service.go index 4b68a433a..042cbeec4 100644 --- a/pkg/isbsvc/jetstream_service.go +++ b/pkg/isbsvc/jetstream_service.go @@ -60,7 +60,7 @@ func WithJetStreamClient(jsClient jsclient.JetStreamClient) JSServiceOption { } } -func (jss *jetStreamSvc) CreateBuffersAndBuckets(ctx context.Context, buffers, buckets []string, opts ...CreateOption) error { +func (jss *jetStreamSvc) CreateBuffersAndBuckets(ctx context.Context, buffers, buckets []string, sideInputsStore string, opts ...CreateOption) error { if len(buffers) == 0 && len(buckets) == 0 { return nil } @@ -86,6 +86,26 @@ func (jss *jetStreamSvc) CreateBuffersAndBuckets(ctx context.Context, buffers, b if err != nil { return fmt.Errorf("failed to get a js context from nats connection, %w", err) } + if sideInputsStore != "" { + bucket := JetStreamSideInputsStoreBucket(sideInputsStore) + if _, err := js.KeyValue(bucket); err != nil { + if !errors.Is(err, nats.ErrBucketNotFound) && !errors.Is(err, nats.ErrStreamNotFound) { + return fmt.Errorf("failed to query information of bucket %q, %w", bucket, err) + } + if _, err := js.CreateKeyValue(&nats.KeyValueConfig{ + Bucket: bucket, + MaxValueSize: 0, + History: 1, // No history + TTL: time.Hour * 24 * 30, // 30 days + MaxBytes: 0, + Storage: nats.FileStorage, + Replicas: 3, + }); err != nil { + return fmt.Errorf("failed to create side inputs bucket %q, %w", bucket, err) + } + log.Infow("Succeeded to create a side inputs bucket", zap.String("bucket", bucket)) + } + } for _, buffer := range buffers { streamName := JetStreamName(buffer) _, err := js.StreamInfo(streamName) @@ -107,7 +127,7 @@ func (jss *jetStreamSvc) CreateBuffersAndBuckets(ctx context.Context, buffers, b }); err != nil { return fmt.Errorf("failed to create stream %q and buffers, %w", streamName, err) } - log.Infow("Succeeded to create a stream and buffers", zap.String("stream", streamName), zap.Strings("buffers", []string{streamName})) + log.Infow("Succeeded to create a stream", zap.String("stream", streamName)) if _, err := js.AddConsumer(streamName, &nats.ConsumerConfig{ Durable: streamName, DeliverPolicy: nats.DeliverAllPolicy, @@ -167,7 +187,7 @@ func (jss *jetStreamSvc) CreateBuffersAndBuckets(ctx context.Context, buffers, b return nil } -func (jss *jetStreamSvc) DeleteBuffersAndBuckets(ctx context.Context, buffers, buckets []string) error { +func (jss *jetStreamSvc) DeleteBuffersAndBuckets(ctx context.Context, buffers, buckets []string, sideInputsStore string) error { if len(buffers) == 0 && len(buckets) == 0 { return nil } @@ -200,10 +220,18 @@ func (jss *jetStreamSvc) DeleteBuffersAndBuckets(ctx context.Context, buffers, b } log.Infow("Succeeded to delete a processor bucket", zap.String("bucket", procBucket)) } + + if sideInputsStore != "" { + sideInputsBucket := JetStreamSideInputsStoreBucket(sideInputsStore) + if err := js.DeleteKeyValue(sideInputsBucket); err != nil && !errors.Is(err, nats.ErrBucketNotFound) && !errors.Is(err, nats.ErrStreamNotFound) { + return fmt.Errorf("failed to delete side inputs bucket %q, %w", sideInputsBucket, err) + } + log.Infow("Succeeded to delete a side inputs bucket", zap.String("bucket", sideInputsBucket)) + } return nil } -func (jss *jetStreamSvc) ValidateBuffersAndBuckets(ctx context.Context, buffers, buckets []string) error { +func (jss *jetStreamSvc) ValidateBuffersAndBuckets(ctx context.Context, buffers, buckets []string, sideInputsStore string) error { if len(buffers) == 0 && len(buckets) == 0 { return nil } @@ -233,6 +261,12 @@ func (jss *jetStreamSvc) ValidateBuffersAndBuckets(ctx context.Context, buffers, return fmt.Errorf("failed to query processor bucket %q, %w", procBucket, err) } } + if sideInputsStore != "" { + sideInputsBucket := JetStreamSideInputsStoreBucket(sideInputsStore) + if _, err := js.KeyValue(sideInputsBucket); err != nil { + return fmt.Errorf("failed to query side inputs store %q, %w", sideInputsBucket, err) + } + } return nil } @@ -325,3 +359,7 @@ func JetStreamOTBucket(bucketName string) string { func JetStreamProcessorBucket(bucketName string) string { return fmt.Sprintf("%s_PROCESSORS", bucketName) } + +func JetStreamSideInputsStoreBucket(sideInputStoreName string) string { + return fmt.Sprintf("%s_SIDE_INPUTS", sideInputStoreName) +} diff --git a/pkg/isbsvc/redis_service.go b/pkg/isbsvc/redis_service.go index c2b9c00b3..d03f2f59e 100644 --- a/pkg/isbsvc/redis_service.go +++ b/pkg/isbsvc/redis_service.go @@ -42,7 +42,7 @@ func NewISBRedisSvc(client *redisclient.RedisClient) ISBService { } // CreateBuffers is used to create the inter-step redis buffers. -func (r *isbsRedisSvc) CreateBuffersAndBuckets(ctx context.Context, buffers, buckets []string, opts ...CreateOption) error { +func (r *isbsRedisSvc) CreateBuffersAndBuckets(ctx context.Context, buffers, buckets []string, sideInputsStore string, opts ...CreateOption) error { if len(buffers) == 0 && len(buckets) == 0 { return nil } @@ -70,7 +70,7 @@ func (r *isbsRedisSvc) CreateBuffersAndBuckets(ctx context.Context, buffers, buc } // DeleteBuffers is used to delete the inter-step redis buffers. -func (r *isbsRedisSvc) DeleteBuffersAndBuckets(ctx context.Context, buffers, buckets []string) error { +func (r *isbsRedisSvc) DeleteBuffersAndBuckets(ctx context.Context, buffers, buckets []string, sideInputsStore string) error { if len(buffers) == 0 && len(buckets) == 0 { return nil } @@ -106,7 +106,7 @@ func (r *isbsRedisSvc) DeleteBuffersAndBuckets(ctx context.Context, buffers, buc } // ValidateBuffers is used to validate inter-step redis buffers to see if the stream/stream group exist -func (r *isbsRedisSvc) ValidateBuffersAndBuckets(ctx context.Context, buffers, buckets []string) error { +func (r *isbsRedisSvc) ValidateBuffersAndBuckets(ctx context.Context, buffers, buckets []string, sideInputsStore string) error { if len(buffers) == 0 && len(buckets) == 0 { return nil } diff --git a/pkg/isbsvc/redis_service_test.go b/pkg/isbsvc/redis_service_test.go index 527c94b87..bcc46e260 100644 --- a/pkg/isbsvc/redis_service_test.go +++ b/pkg/isbsvc/redis_service_test.go @@ -42,10 +42,10 @@ func TestIsbsRedisSvc_Buffers(t *testing.T) { buffers := []string{buffer} redisClient := redisclient.NewRedisClient(redisOptions) isbsRedisSvc := NewISBRedisSvc(redisClient) - assert.NoError(t, isbsRedisSvc.CreateBuffersAndBuckets(ctx, buffers, nil)) + assert.NoError(t, isbsRedisSvc.CreateBuffersAndBuckets(ctx, buffers, nil, "")) // validate buffer - assert.NoError(t, isbsRedisSvc.ValidateBuffersAndBuckets(ctx, buffers, nil)) + assert.NoError(t, isbsRedisSvc.ValidateBuffersAndBuckets(ctx, buffers, nil, "")) // Verify // Add some data @@ -78,5 +78,5 @@ func TestIsbsRedisSvc_Buffers(t *testing.T) { } // delete buffer - assert.NoError(t, isbsRedisSvc.DeleteBuffersAndBuckets(ctx, buffers, nil)) + assert.NoError(t, isbsRedisSvc.DeleteBuffersAndBuckets(ctx, buffers, nil, "")) } diff --git a/pkg/reconciler/pipeline/controller.go b/pkg/reconciler/pipeline/controller.go index 7a8f8ece6..f6ef571a0 100644 --- a/pkg/reconciler/pipeline/controller.go +++ b/pkg/reconciler/pipeline/controller.go @@ -184,6 +184,13 @@ func (r *pipelineReconciler) reconcileNonLifecycleChanges(ctx context.Context, p return ctrl.Result{}, fmt.Errorf("isbsvc not ready") } + // Create or update the Side Inputs Manager deployments + if err := r.createOrUpdateSIMDeployments(ctx, pl, isbSvc.Status.Config); err != nil { + log.Errorw("Failed to create or update Side Inputs Manager deployments", zap.Error(err)) + pl.Status.MarkDeployFailed("CreateOrUpdateSIMDeploymentsFailed", err.Error()) + return ctrl.Result{}, err + } + existingObjs, err := r.findExistingVertices(ctx, pl) if err != nil { log.Errorw("Failed to find existing vertices", zap.Error(err)) @@ -249,6 +256,7 @@ func (r *pipelineReconciler) reconcileNonLifecycleChanges(ctx context.Context, p pl.Status.MarkDeployFailed("DeleteStaleVertexFailed", err.Error()) return ctrl.Result{}, fmt.Errorf("failed to delete vertex, err: %w", err) } + log.Infow("Deleted stale vertex successfully", zap.String("vertex", v.Name)) } // create batch job @@ -262,6 +270,7 @@ func (r *pipelineReconciler) reconcileNonLifecycleChanges(ctx context.Context, p bks = append(bks, k) } args := []string{fmt.Sprintf("--buffers=%s", strings.Join(bfs, ",")), fmt.Sprintf("--buckets=%s", strings.Join(bks, ","))} + args = append(args, fmt.Sprintf("--side-inputs-store=%s", pl.GetSideInputsStoreName())) batchJob := buildISBBatchJob(pl, r.image, isbSvc.Status.Config, "isbsvc-create", args, "create") if err := r.client.Create(ctx, batchJob); err != nil && !apierrors.IsAlreadyExists(err) { pl.Status.MarkDeployFailed("CreateISBSvcCreatingJobFailed", err.Error()) @@ -393,6 +402,81 @@ func (r *pipelineReconciler) findExistingVertices(ctx context.Context, pl *dfv1. return result, nil } +// Create or update Side Inputs Mapager deployments +func (r *pipelineReconciler) createOrUpdateSIMDeployments(ctx context.Context, pl *dfv1.Pipeline, isbSvcConfig dfv1.BufferServiceConfig) error { + log := logging.FromContext(ctx) + isbSvcType, envs := sharedutil.GetIsbSvcEnvVars(isbSvcConfig) + envs = append(envs, corev1.EnvVar{Name: dfv1.EnvPipelineName, Value: pl.Name}) + req := dfv1.GetSideInputDeploymentReq{ + ISBSvcType: isbSvcType, + Image: r.image, + PullPolicy: corev1.PullPolicy(sharedutil.LookupEnvStringOr(dfv1.EnvImagePullPolicy, "")), + Env: envs, + } + + newObjs, err := pl.GetSideInputsManagerDeployments(req) + if err != nil { + pl.Status.MarkDeployFailed("BuildSIMObjsFailed", err.Error()) + return fmt.Errorf("failed to build Side Inputs Manager Deployments, %w", err) + } + existingObjs, err := r.findExistingSIMDeploys(ctx, pl) + if err != nil { + pl.Status.MarkDeployFailed("FindExistingSIMFailed", err.Error()) + return fmt.Errorf("failed to find existing Side Inputs Manager Deployments, %w", err) + } + for _, newObj := range newObjs { + deployHash := sharedutil.MustHash(newObj.Spec) + if newObj.Annotations == nil { + newObj.Annotations = make(map[string]string) + } + newObj.Annotations[dfv1.KeyHash] = deployHash + if oldObj, existing := existingObjs[newObj.Name]; !existing { + if err := r.client.Create(ctx, newObj); err != nil { + if apierrors.IsAlreadyExists(err) { // probably somebody else already created it + continue + } else { + pl.Status.MarkDeployFailed("CreateSIMDeploymentFailed", err.Error()) + return fmt.Errorf("failed to create Side Inputs Manager Deployment %q, %w", newObj.Name, err) + } + } + log.Infow("Created Side Inputs Manager Deployment successfully", zap.String("deployment", newObj.Name)) + } else { + if oldObj.GetAnnotations()[dfv1.KeyHash] != newObj.GetAnnotations()[dfv1.KeyHash] { // need to update + oldObj.Spec = newObj.Spec + oldObj.Annotations[dfv1.KeyHash] = newObj.GetAnnotations()[dfv1.KeyHash] + if err := r.client.Update(ctx, &oldObj); err != nil { + pl.Status.MarkDeployFailed("UpdateSIMDeploymentFailed", err.Error()) + return fmt.Errorf("failed to update Side Inputs Manager Deployment %q, %w", oldObj.Name, err) + } + log.Infow("Updated Side Inputs Manager Deployment successfully", zap.String("deployment", oldObj.Name)) + } + delete(existingObjs, oldObj.Name) + } + } + for _, v := range existingObjs { + if err := r.client.Delete(ctx, &v); err != nil { + pl.Status.MarkDeployFailed("DeleteStaleSIMDeploymentFailed", err.Error()) + return fmt.Errorf("failed to delete stale Side Inputs Manager Deployment %q, %w", v.Name, err) + } + log.Infow("Deleted stale Side Inputs Manager Deployment successfully", zap.String("deployment", v.Name)) + } + return nil +} + +// Find existing Side Inputs Manager Deployment objects. +func (r *pipelineReconciler) findExistingSIMDeploys(ctx context.Context, pl *dfv1.Pipeline) (map[string]appv1.Deployment, error) { + deployments := &appv1.DeploymentList{} + selector, _ := labels.Parse(dfv1.KeyPipelineName + "=" + pl.Name + "," + dfv1.KeyComponent + "=" + dfv1.ComponentSideInputManager) + if err := r.client.List(ctx, deployments, &client.ListOptions{Namespace: pl.Namespace, LabelSelector: selector}); err != nil { + return nil, fmt.Errorf("failed to list existing Side Inputs Manager deployments: %w", err) + } + result := make(map[string]appv1.Deployment) + for _, d := range deployments.Items { + result[d.Name] = d + } + return result, nil +} + func (r *pipelineReconciler) cleanUpBuffers(ctx context.Context, pl *dfv1.Pipeline, log *zap.SugaredLogger) error { allBuffers := pl.GetAllBuffers() allBuckets := pl.GetAllBuckets() @@ -414,6 +498,7 @@ func (r *pipelineReconciler) cleanUpBuffers(ctx context.Context, pl *dfv1.Pipeli args := []string{} args = append(args, fmt.Sprintf("--buffers=%s", strings.Join(allBuffers, ","))) args = append(args, fmt.Sprintf("--buckets=%s", strings.Join(allBuckets, ","))) + args = append(args, fmt.Sprintf("--side-inputs-store=%s", pl.GetSideInputsStoreName())) batchJob := buildISBBatchJob(pl, r.image, isbSvc.Status.Config, "isbsvc-delete", args, "cleanup") batchJob.OwnerReferences = []metav1.OwnerReference{} diff --git a/pkg/reconciler/pipeline/controller_test.go b/pkg/reconciler/pipeline/controller_test.go index 312c9ac06..1eb9d9ca2 100644 --- a/pkg/reconciler/pipeline/controller_test.go +++ b/pkg/reconciler/pipeline/controller_test.go @@ -416,3 +416,103 @@ func TestCreateOrUpdateDaemon(t *testing.T) { assert.Equal(t, "test-pl-daemon", deployList.Items[0].Name) }) } + +func Test_createOrUpdateSIMDeployments(t *testing.T) { + cl := fake.NewClientBuilder().Build() + ctx := context.TODO() + r := &pipelineReconciler{ + client: cl, + scheme: scheme.Scheme, + config: fakeConfig, + image: testFlowImage, + logger: zaptest.NewLogger(t).Sugar(), + } + + t.Run("no side inputs", func(t *testing.T) { + err := r.createOrUpdateSIMDeployments(ctx, testPipeline, fakeIsbSvcConfig) + assert.NoError(t, err) + deployList := appv1.DeploymentList{} + err = cl.List(context.Background(), &deployList, &client.ListOptions{Namespace: testNamespace, LabelSelector: labels.SelectorFromSet(labels.Set{dfv1.KeyComponent: dfv1.ComponentSideInputManager})}) + assert.NoError(t, err) + assert.Len(t, deployList.Items, 0) + }) + + t.Run("one side input", func(t *testing.T) { + testObj := testPipeline.DeepCopy() + testObj.Spec.SideInputs = []dfv1.SideInput{ + { + Name: "s1", + Container: &dfv1.Container{ + Image: "test", + }, + Trigger: &dfv1.SideInputTrigger{ + Schedule: pointer.String("1 * * * *"), + }, + }, + } + err := r.createOrUpdateSIMDeployments(ctx, testObj, fakeIsbSvcConfig) + assert.NoError(t, err) + deployList := appv1.DeploymentList{} + err = cl.List(context.Background(), &deployList, &client.ListOptions{Namespace: testNamespace, LabelSelector: labels.SelectorFromSet(labels.Set{dfv1.KeyComponent: dfv1.ComponentSideInputManager})}) + assert.NoError(t, err) + assert.Len(t, deployList.Items, 1) + assert.Equal(t, testObj.GetSideInputsManagerDeploymentName("s1"), deployList.Items[0].Name) + }) + + t.Run("two side inputs", func(t *testing.T) { + testObj := testPipeline.DeepCopy() + testObj.Spec.SideInputs = []dfv1.SideInput{ + { + Name: "s1", + Container: &dfv1.Container{ + Image: "test", + }, + Trigger: &dfv1.SideInputTrigger{ + Schedule: pointer.String("1 * * * *"), + }, + }, + { + Name: "s2", + Container: &dfv1.Container{ + Image: "test", + }, + Trigger: &dfv1.SideInputTrigger{ + Schedule: pointer.String("1 * * * *"), + }, + }, + } + err := r.createOrUpdateSIMDeployments(ctx, testObj, fakeIsbSvcConfig) + assert.NoError(t, err) + deployList := appv1.DeploymentList{} + err = cl.List(context.Background(), &deployList, &client.ListOptions{Namespace: testNamespace, LabelSelector: labels.SelectorFromSet(labels.Set{dfv1.KeyComponent: dfv1.ComponentSideInputManager})}) + assert.NoError(t, err) + assert.Len(t, deployList.Items, 2) + assert.Equal(t, testObj.GetSideInputsManagerDeploymentName("s1"), deployList.Items[0].Name) + assert.Equal(t, testObj.GetSideInputsManagerDeploymentName("s2"), deployList.Items[1].Name) + }) + + t.Run("update side inputs", func(t *testing.T) { + testObj := testPipeline.DeepCopy() + testObj.Spec.SideInputs = []dfv1.SideInput{ + { + Name: "s1", + Container: &dfv1.Container{ + Image: "test", + }, + Trigger: &dfv1.SideInputTrigger{ + Schedule: pointer.String("1 * * * *"), + }, + }, + } + err := r.createOrUpdateSIMDeployments(ctx, testObj, fakeIsbSvcConfig) + assert.NoError(t, err) + testObj.Spec.SideInputs[0].Name = "s2" + err = r.createOrUpdateSIMDeployments(ctx, testObj, fakeIsbSvcConfig) + assert.NoError(t, err) + deployList := appv1.DeploymentList{} + err = cl.List(context.Background(), &deployList, &client.ListOptions{Namespace: testNamespace, LabelSelector: labels.SelectorFromSet(labels.Set{dfv1.KeyComponent: dfv1.ComponentSideInputManager})}) + assert.NoError(t, err) + assert.Len(t, deployList.Items, 1) + assert.Equal(t, testObj.GetSideInputsManagerDeploymentName("s2"), deployList.Items[0].Name) + }) +} diff --git a/pkg/reconciler/pipeline/validate.go b/pkg/reconciler/pipeline/validate.go index b988a01cc..62ae6ab7d 100644 --- a/pkg/reconciler/pipeline/validate.go +++ b/pkg/reconciler/pipeline/validate.go @@ -173,6 +173,11 @@ func ValidatePipeline(pl *dfv1.Pipeline) error { return fmt.Errorf("the length of the pipeline name plus the vertex name is over the max limit. (%s-%s), %v", pl.Name, v.Name, errs) } } + + if err := validateSideInputs(*pl); err != nil { + return err + } + return nil } @@ -259,10 +264,54 @@ func validateUDF(udf dfv1.UDF) error { return nil } +func validateSideInputs(pl dfv1.Pipeline) error { + sideInputs := make(map[string]bool) + for _, si := range pl.Spec.SideInputs { + if si.Name == "" { + return fmt.Errorf("side input name is missing") + } + if _, existing := sideInputs[si.Name]; existing { + return fmt.Errorf("side input %q is defined more than once", si.Name) + } + sideInputs[si.Name] = true + if si.Container == nil { + return fmt.Errorf("side input %q: container is missing", si.Name) + } + if si.Container.Image == "" { + return fmt.Errorf("side input %q: image is missing", si.Name) + } + if si.Trigger == nil { + return fmt.Errorf("side input %q: trigger is missing", si.Name) + } + if si.Trigger.Schedule == nil && si.Trigger.Interval == nil { + return fmt.Errorf("side input %q: either schedule or interval is required", si.Name) + } + if si.Trigger.Schedule != nil && si.Trigger.Interval != nil { + return fmt.Errorf("side input %q: schedule and interval cannot be used together", si.Name) + } + } + for _, v := range pl.Spec.Vertices { + namesInVertex := make(map[string]bool) + for _, si := range v.SideInputs { + if _, existing := sideInputs[si]; !existing { + return fmt.Errorf("vertex %q: side input %q is not defined", v.Name, si) + } + if _, existing := namesInVertex[si]; existing { + return fmt.Errorf("vertex %q: side input %q is defined more than once", v.Name, si) + } + namesInVertex[si] = true + } + } + return nil +} + func isReservedContainerName(name string) bool { return name == dfv1.CtrInit || name == dfv1.CtrMain || name == dfv1.CtrUdf || name == dfv1.CtrUdsink || - name == dfv1.CtrUdtransformer + name == dfv1.CtrUdtransformer || + name == dfv1.CtrUdSideInput || + name == dfv1.CtrInitSideInputs || + name == dfv1.CtrSideInputsWatcher } diff --git a/pkg/reconciler/pipeline/validate_test.go b/pkg/reconciler/pipeline/validate_test.go index 22b12b914..a7975b6b9 100644 --- a/pkg/reconciler/pipeline/validate_test.go +++ b/pkg/reconciler/pipeline/validate_test.go @@ -541,3 +541,75 @@ func TestValidateUDF(t *testing.T) { assert.Contains(t, err.Error(), `"length" is missing`) }) } + +func Test_validateSideInputs(t *testing.T) { + testObj := testPipeline.DeepCopy() + err := validateSideInputs(*testObj) + assert.NoError(t, err) + testObj.Spec.SideInputs = []dfv1.SideInput{ + {Name: ""}, + } + err = validateSideInputs(*testObj) + assert.Error(t, err) + assert.Contains(t, err.Error(), `name is missing`) + + testObj.Spec.SideInputs = []dfv1.SideInput{ + {Name: "s1"}, + } + err = validateSideInputs(*testObj) + assert.Error(t, err) + assert.Contains(t, err.Error(), `container is missing`) + + testObj.Spec.SideInputs[0].Container = &dfv1.Container{} + err = validateSideInputs(*testObj) + assert.Error(t, err) + assert.Contains(t, err.Error(), `image is missing`) + + testObj.Spec.SideInputs[0].Container.Image = "my-image:latest" + err = validateSideInputs(*testObj) + assert.Error(t, err) + assert.Contains(t, err.Error(), `trigger is missing`) + + testObj.Spec.SideInputs[0].Trigger = &dfv1.SideInputTrigger{} + err = validateSideInputs(*testObj) + assert.Error(t, err) + assert.Contains(t, err.Error(), `either schedule or interval is required`) + + testObj.Spec.SideInputs[0].Trigger.Interval = &metav1.Duration{Duration: time.Duration(200 * time.Second)} + testObj.Spec.SideInputs[0].Trigger.Schedule = pointer.String("0 2 * * *") + err = validateSideInputs(*testObj) + assert.Error(t, err) + assert.Contains(t, err.Error(), `schedule and interval cannot be used together`) + testObj.Spec.SideInputs[0].Trigger.Schedule = nil + + testObj.Spec.SideInputs = append(testObj.Spec.SideInputs, dfv1.SideInput{ + Name: "s1", + Container: &dfv1.Container{ + Image: "my-image:latest", + }, + Trigger: &dfv1.SideInputTrigger{ + Interval: &metav1.Duration{Duration: time.Duration(200 * time.Second)}, + }, + }) + err = validateSideInputs(*testObj) + assert.Error(t, err) + assert.Contains(t, err.Error(), `is defined more than once`) + + testObj.Spec.SideInputs[1].Name = "s2" + err = validateSideInputs(*testObj) + assert.NoError(t, err) + + testObj.Spec.Vertices[1].SideInputs = []string{"s1", "s1"} + err = validateSideInputs(*testObj) + assert.Error(t, err) + assert.Contains(t, err.Error(), `is defined more than once`) + + testObj.Spec.Vertices[1].SideInputs = []string{"s1", "s3"} + err = validateSideInputs(*testObj) + assert.Error(t, err) + assert.Contains(t, err.Error(), `is not defined`) + + testObj.Spec.Vertices[1].SideInputs = []string{"s1", "s2"} + err = validateSideInputs(*testObj) + assert.NoError(t, err) +} diff --git a/pkg/reconciler/vertex/controller.go b/pkg/reconciler/vertex/controller.go index 1e0716b8d..5d9395589 100644 --- a/pkg/reconciler/vertex/controller.go +++ b/pkg/reconciler/vertex/controller.go @@ -329,10 +329,11 @@ func (r *vertexReconciler) buildReduceVertexPVCSpec(vertex *dfv1.Vertex, replica func (r *vertexReconciler) buildPodSpec(vertex *dfv1.Vertex, pl *dfv1.Pipeline, isbSvcConfig dfv1.BufferServiceConfig, replicaIndex int) (*corev1.PodSpec, error) { isbSvcType, envs := sharedutil.GetIsbSvcEnvVars(isbSvcConfig) podSpec, err := vertex.GetPodSpec(dfv1.GetVertexPodSpecReq{ - ISBSvcType: isbSvcType, - Image: r.image, - PullPolicy: corev1.PullPolicy(sharedutil.LookupEnvStringOr(dfv1.EnvImagePullPolicy, "")), - Env: envs, + ISBSvcType: isbSvcType, + Image: r.image, + PullPolicy: corev1.PullPolicy(sharedutil.LookupEnvStringOr(dfv1.EnvImagePullPolicy, "")), + Env: envs, + SideInputsStoreName: pl.GetSideInputsStoreName(), }) if err != nil { return nil, fmt.Errorf("failed to generate pod spec, error: %w", err) diff --git a/pkg/reconciler/vertex/controller_test.go b/pkg/reconciler/vertex/controller_test.go index a0011da20..7085476ea 100644 --- a/pkg/reconciler/vertex/controller_test.go +++ b/pkg/reconciler/vertex/controller_test.go @@ -32,6 +32,7 @@ import ( metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/apimachinery/pkg/labels" "k8s.io/client-go/kubernetes/scheme" + "k8s.io/utils/pointer" "sigs.k8s.io/controller-runtime/pkg/client" "sigs.k8s.io/controller-runtime/pkg/client/fake" ) @@ -501,4 +502,54 @@ func Test_reconcile(t *testing.T) { assert.True(t, strings.HasPrefix(pods.Items[0].Name, testVertexName+"-0-")) assert.Equal(t, 2, len(pods.Items[0].Spec.Containers)) }) + + t.Run("test reconcile udf with side inputs", func(t *testing.T) { + cl := fake.NewClientBuilder().Build() + ctx := context.TODO() + testIsbSvc := testNativeRedisIsbSvc.DeepCopy() + testIsbSvc.Status.MarkConfigured() + testIsbSvc.Status.MarkDeployed() + err := cl.Create(ctx, testIsbSvc) + assert.Nil(t, err) + testPl := testPipeline.DeepCopy() + testPl.Spec.SideInputs = []dfv1.SideInput{ + { + Name: "s1", + Container: &dfv1.Container{ + Image: "test", + }, + Trigger: &dfv1.SideInputTrigger{ + Schedule: pointer.String("1 * * * *"), + }, + }, + } + testPl.Spec.Vertices[1].SideInputs = []string{"s1"} + err = cl.Create(ctx, testPl) + assert.Nil(t, err) + r := &vertexReconciler{ + client: cl, + scheme: scheme.Scheme, + config: fakeConfig, + image: testFlowImage, + scaler: scaling.NewScaler(cl), + logger: zaptest.NewLogger(t).Sugar(), + } + testObj := testVertex.DeepCopy() + testObj.Spec.UDF = &dfv1.UDF{ + Builtin: &dfv1.Function{ + Name: "cat", + }, + } + testObj.Spec.SideInputs = []string{"s1"} + _, err = r.reconcile(ctx, testObj) + assert.NoError(t, err) + pods := &corev1.PodList{} + selector, _ := labels.Parse(dfv1.KeyPipelineName + "=" + testPipelineName + "," + dfv1.KeyVertexName + "=" + testVertexSpecName) + err = r.client.List(ctx, pods, &client.ListOptions{Namespace: testNamespace, LabelSelector: selector}) + assert.NoError(t, err) + assert.Equal(t, 1, len(pods.Items)) + assert.True(t, strings.HasPrefix(pods.Items[0].Name, testVertexName+"-0-")) + assert.Equal(t, 3, len(pods.Items[0].Spec.Containers)) + assert.Equal(t, 2, len(pods.Items[0].Spec.InitContainers)) + }) } diff --git a/pkg/sdkclient/error/error.go b/pkg/sdkclient/error/error.go index 54b6e8f67..7c4ffbfb8 100644 --- a/pkg/sdkclient/error/error.go +++ b/pkg/sdkclient/error/error.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package error import ( diff --git a/pkg/sdkclient/error/error_test.go b/pkg/sdkclient/error/error_test.go index 9c22ee13a..4155bf8a0 100644 --- a/pkg/sdkclient/error/error_test.go +++ b/pkg/sdkclient/error/error_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package error import ( diff --git a/pkg/sdkclient/sink/client/client.go b/pkg/sdkclient/sink/client/client.go index eba2760d9..528b325dd 100644 --- a/pkg/sdkclient/sink/client/client.go +++ b/pkg/sdkclient/sink/client/client.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package client import ( diff --git a/pkg/sdkclient/sink/client/interface.go b/pkg/sdkclient/sink/client/interface.go index 96c7b6ef2..c34299c64 100644 --- a/pkg/sdkclient/sink/client/interface.go +++ b/pkg/sdkclient/sink/client/interface.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package client import ( diff --git a/pkg/sdkclient/sink/client/options.go b/pkg/sdkclient/sink/client/options.go index 4ac819f8d..db1880dba 100644 --- a/pkg/sdkclient/sink/client/options.go +++ b/pkg/sdkclient/sink/client/options.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package client import "time" diff --git a/pkg/sdkclient/sink/clienttest/client_test.go b/pkg/sdkclient/sink/clienttest/client_test.go index ebf3f4c28..78294c8ec 100644 --- a/pkg/sdkclient/sink/clienttest/client_test.go +++ b/pkg/sdkclient/sink/clienttest/client_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package clienttest import ( diff --git a/pkg/sdkclient/sink/clienttest/clienttest.go b/pkg/sdkclient/sink/clienttest/clienttest.go index 20e353f13..d075423af 100644 --- a/pkg/sdkclient/sink/clienttest/clienttest.go +++ b/pkg/sdkclient/sink/clienttest/clienttest.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package clienttest import ( diff --git a/pkg/sdkclient/udf/client/client.go b/pkg/sdkclient/udf/client/client.go index d1e70faeb..1f9c99cde 100644 --- a/pkg/sdkclient/udf/client/client.go +++ b/pkg/sdkclient/udf/client/client.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package client import ( diff --git a/pkg/sdkclient/udf/client/client_resolver.go b/pkg/sdkclient/udf/client/client_resolver.go index acc48e2ac..a7eaa3ece 100644 --- a/pkg/sdkclient/udf/client/client_resolver.go +++ b/pkg/sdkclient/udf/client/client_resolver.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package client import ( diff --git a/pkg/sdkclient/udf/client/interface.go b/pkg/sdkclient/udf/client/interface.go index 9083baefe..7c0a88748 100644 --- a/pkg/sdkclient/udf/client/interface.go +++ b/pkg/sdkclient/udf/client/interface.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package client import ( diff --git a/pkg/sdkclient/udf/client/options.go b/pkg/sdkclient/udf/client/options.go index e3a21e6d2..89a3d37cd 100644 --- a/pkg/sdkclient/udf/client/options.go +++ b/pkg/sdkclient/udf/client/options.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package client import "time" diff --git a/pkg/sdkclient/udf/clienttest/client_test.go b/pkg/sdkclient/udf/clienttest/client_test.go index 87bc8818f..4e981f2ca 100644 --- a/pkg/sdkclient/udf/clienttest/client_test.go +++ b/pkg/sdkclient/udf/clienttest/client_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package clienttest import ( diff --git a/pkg/sdkclient/udf/clienttest/clienttest.go b/pkg/sdkclient/udf/clienttest/clienttest.go index 993c1ca15..4b30db250 100644 --- a/pkg/sdkclient/udf/clienttest/clienttest.go +++ b/pkg/sdkclient/udf/clienttest/clienttest.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package clienttest import ( diff --git a/pkg/sideinputs/doc.go b/pkg/sideinputs/doc.go new file mode 100644 index 000000000..a0f4150e7 --- /dev/null +++ b/pkg/sideinputs/doc.go @@ -0,0 +1,23 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package sideinputs is used for Side Inputs features. +// +// It contains the following subpackages: +// - initializer: used for init container on the vertex pod to initialize the Side Inputs data. +// - manager: used for run the service in the numa container of a Side Inputs Manager. +// - watcher: used for the service in the sidecar container of a vertex pod for watching Side Inputs data changes. +package sideinputs diff --git a/pkg/sideinputs/initializer/doc.go b/pkg/sideinputs/initializer/doc.go new file mode 100644 index 000000000..734880f46 --- /dev/null +++ b/pkg/sideinputs/initializer/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package initializer is used for init container on the vertex pod to initialize the Side Inputs data. +package initializer diff --git a/pkg/sideinputs/initializer/initializer.go b/pkg/sideinputs/initializer/initializer.go new file mode 100644 index 000000000..f3ea9b31b --- /dev/null +++ b/pkg/sideinputs/initializer/initializer.go @@ -0,0 +1,76 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package initializer + +import ( + "context" + "fmt" + "path" + + "go.uber.org/zap" + + dfv1 "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" + "github.com/numaproj/numaflow/pkg/isbsvc" + jsclient "github.com/numaproj/numaflow/pkg/shared/clients/nats" + "github.com/numaproj/numaflow/pkg/shared/logging" +) + +type sideInputsInitializer struct { + isbSvcType dfv1.ISBSvcType + pipelineName string + sideInputsStore string + sideInputs []string +} + +func NewSideInputsInitializer(isbSvcType dfv1.ISBSvcType, pipelineName, sideInputsStore string, sideInputs []string) *sideInputsInitializer { + return &sideInputsInitializer{ + isbSvcType: isbSvcType, + sideInputsStore: sideInputsStore, + pipelineName: pipelineName, + sideInputs: sideInputs, + } +} + +func (sii *sideInputsInitializer) Run(ctx context.Context) error { + log := logging.FromContext(ctx) + log.Infow("Starting Side Inputs Initializer", zap.Strings("sideInputs", sii.sideInputs)) + + var isbSvcClient isbsvc.ISBService + var err error + switch sii.isbSvcType { + case dfv1.ISBSvcTypeRedis: + return fmt.Errorf("unsupported isbsvc type %q", sii.isbSvcType) + case dfv1.ISBSvcTypeJetStream: + isbSvcClient, err = isbsvc.NewISBJetStreamSvc(sii.pipelineName, isbsvc.WithJetStreamClient(jsclient.NewInClusterJetStreamClient())) + if err != nil { + log.Errorw("Failed to get an ISB Service client.", zap.Error(err)) + return err + } + default: + return fmt.Errorf("unrecognized isbsvc type %q", sii.isbSvcType) + } + + // TODO(SI): do something + // Wait for the data is ready in the side input store, and then copy the data to the disk + fmt.Printf("ISB Svc Client nil: %v\n", isbSvcClient == nil) + for _, sideInput := range sii.sideInputs { + p := path.Join(dfv1.PathSideInputsMount, sideInput) + fmt.Printf("Initializing side input data for %q\n", p) + } + + return nil +} diff --git a/pkg/sideinputs/manager/doc.go b/pkg/sideinputs/manager/doc.go new file mode 100644 index 000000000..cb18c9d84 --- /dev/null +++ b/pkg/sideinputs/manager/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package manager is used for run the service in the numa container of a Side Inputs Manager. +package manager diff --git a/pkg/sideinputs/manager/manager.go b/pkg/sideinputs/manager/manager.go new file mode 100644 index 000000000..3db3341c9 --- /dev/null +++ b/pkg/sideinputs/manager/manager.go @@ -0,0 +1,75 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package manager + +import ( + "context" + "fmt" + + "go.uber.org/zap" + + dfv1 "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" + "github.com/numaproj/numaflow/pkg/isbsvc" + jsclient "github.com/numaproj/numaflow/pkg/shared/clients/nats" + "github.com/numaproj/numaflow/pkg/shared/logging" +) + +type sideInputsManager struct { + isbSvcType dfv1.ISBSvcType + pipelineName string + sideInputsStore string + sideInput *dfv1.SideInput +} + +func NewSideInputsManager(isbSvcType dfv1.ISBSvcType, pipelineName, sideInputsStore string, sideInput *dfv1.SideInput) *sideInputsManager { + return &sideInputsManager{ + isbSvcType: isbSvcType, + sideInputsStore: sideInputsStore, + pipelineName: pipelineName, + sideInput: sideInput, + } +} + +func (sim *sideInputsManager) Start(ctx context.Context) error { + log := logging.FromContext(ctx) + log.Infof("Starting Side Inputs Manager for %q", sim.sideInput.Name) + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + var isbSvcClient isbsvc.ISBService + var err error + switch sim.isbSvcType { + case dfv1.ISBSvcTypeRedis: + return fmt.Errorf("unsupported isbsvc type %q", sim.isbSvcType) + case dfv1.ISBSvcTypeJetStream: + isbSvcClient, err = isbsvc.NewISBJetStreamSvc(sim.pipelineName, isbsvc.WithJetStreamClient(jsclient.NewInClusterJetStreamClient())) + if err != nil { + log.Errorw("Failed to get an ISB Service client.", zap.Error(err)) + return err + } + default: + return fmt.Errorf("unrecognized isbsvc type %q", sim.isbSvcType) + } + + // TODO(SI): do something + // Periodically call the ud container and write data to the store. + fmt.Printf("ISB Svc Client nil: %v\n", isbSvcClient == nil) + fmt.Printf("Pipeline: %s, SideInput: %s\n", sim.pipelineName, sim.sideInput.Name) + + <-ctx.Done() + return nil +} diff --git a/pkg/sideinputs/watcher/doc.go b/pkg/sideinputs/watcher/doc.go new file mode 100644 index 000000000..64959aae8 --- /dev/null +++ b/pkg/sideinputs/watcher/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package watcher is used for the service in the sidecar container of a vertex pod for watching Side Inputs data changes. +package watcher diff --git a/pkg/sideinputs/watcher/watcher.go b/pkg/sideinputs/watcher/watcher.go new file mode 100644 index 000000000..3660696f8 --- /dev/null +++ b/pkg/sideinputs/watcher/watcher.go @@ -0,0 +1,79 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +package watcher + +import ( + "context" + "fmt" + "path" + + "go.uber.org/zap" + + dfv1 "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" + "github.com/numaproj/numaflow/pkg/isbsvc" + jsclient "github.com/numaproj/numaflow/pkg/shared/clients/nats" + "github.com/numaproj/numaflow/pkg/shared/logging" +) + +type sideInputsWatcher struct { + isbSvcType dfv1.ISBSvcType + pipelineName string + sideInputsStore string + sideInputs []string +} + +func NewSideInputsWatcher(isbSvcType dfv1.ISBSvcType, pipelineName, sideInputsStore string, sideInputs []string) *sideInputsWatcher { + return &sideInputsWatcher{ + isbSvcType: isbSvcType, + sideInputsStore: sideInputsStore, + pipelineName: pipelineName, + sideInputs: sideInputs, + } +} + +func (siw *sideInputsWatcher) Start(ctx context.Context) error { + log := logging.FromContext(ctx) + log.Infow("Starting Side Inputs Watcher", zap.Strings("sideInputs", siw.sideInputs)) + ctx, cancel := context.WithCancel(ctx) + defer cancel() + + var isbSvcClient isbsvc.ISBService + var err error + switch siw.isbSvcType { + case dfv1.ISBSvcTypeRedis: + return fmt.Errorf("unsupported isbsvc type %q", siw.isbSvcType) + case dfv1.ISBSvcTypeJetStream: + isbSvcClient, err = isbsvc.NewISBJetStreamSvc(siw.pipelineName, isbsvc.WithJetStreamClient(jsclient.NewInClusterJetStreamClient())) + if err != nil { + log.Errorw("Failed to get an ISB Service client.", zap.Error(err)) + return err + } + default: + return fmt.Errorf("unrecognized isbsvc type %q", siw.isbSvcType) + } + + // TODO(SI): do something + // Watch the side inputs store for changes, and write to disk + fmt.Printf("ISB Svc Client nil: %v\n", isbSvcClient == nil) + for _, sideInput := range siw.sideInputs { + p := path.Join(dfv1.PathSideInputsMount, sideInput) + fmt.Printf("Initializing side input data for %q\n", p) + } + + <-ctx.Done() + return nil +} diff --git a/pkg/watermark/wmb/checker_test.go b/pkg/watermark/wmb/checker_test.go index efd4e4034..509a1ecda 100644 --- a/pkg/watermark/wmb/checker_test.go +++ b/pkg/watermark/wmb/checker_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package wmb import ( diff --git a/pkg/watermark/wmb/idle_manager_test.go b/pkg/watermark/wmb/idle_manager_test.go index 73865c6b7..8cf1db6e5 100644 --- a/pkg/watermark/wmb/idle_manager_test.go +++ b/pkg/watermark/wmb/idle_manager_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package wmb import ( diff --git a/server/doc.go b/server/doc.go new file mode 100644 index 000000000..171c60c20 --- /dev/null +++ b/server/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package server is used for running UX backend server. +package server diff --git a/webhook/cmd/start.go b/webhook/cmd/start.go index bb1300649..8db351ac7 100644 --- a/webhook/cmd/start.go +++ b/webhook/cmd/start.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package cmd import ( @@ -5,11 +21,6 @@ import ( "os" "strconv" - dfv1 "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" - "github.com/numaproj/numaflow/pkg/client/clientset/versioned" - "github.com/numaproj/numaflow/pkg/shared/logging" - sharedutil "github.com/numaproj/numaflow/pkg/shared/util" - "github.com/numaproj/numaflow/webhook" "go.uber.org/zap" "k8s.io/apimachinery/pkg/runtime" "k8s.io/apimachinery/pkg/runtime/schema" @@ -17,6 +28,12 @@ import ( "k8s.io/client-go/rest" "k8s.io/client-go/tools/clientcmd" "sigs.k8s.io/controller-runtime/pkg/manager/signals" + + dfv1 "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" + "github.com/numaproj/numaflow/pkg/client/clientset/versioned" + "github.com/numaproj/numaflow/pkg/shared/logging" + sharedutil "github.com/numaproj/numaflow/pkg/shared/util" + "github.com/numaproj/numaflow/webhook" ) const ( diff --git a/webhook/doc.go b/webhook/doc.go new file mode 100644 index 000000000..caa205454 --- /dev/null +++ b/webhook/doc.go @@ -0,0 +1,18 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + +// Package webhook is used for running validating admission webhook. +package webhook diff --git a/webhook/validator/isbsvc.go b/webhook/validator/isbsvc.go index 3f9acf900..aefc19fab 100644 --- a/webhook/validator/isbsvc.go +++ b/webhook/validator/isbsvc.go @@ -1,13 +1,30 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package validator import ( "context" + admissionv1 "k8s.io/api/admission/v1" + "k8s.io/client-go/kubernetes" + dfv1 "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" "github.com/numaproj/numaflow/pkg/client/clientset/versioned/typed/numaflow/v1alpha1" isbsvccontroller "github.com/numaproj/numaflow/pkg/reconciler/isbsvc" - admissionv1 "k8s.io/api/admission/v1" - "k8s.io/client-go/kubernetes" ) type isbsvcValidator struct { diff --git a/webhook/validator/isbsvc_test.go b/webhook/validator/isbsvc_test.go index 866c5fb1f..a2ca05c42 100644 --- a/webhook/validator/isbsvc_test.go +++ b/webhook/validator/isbsvc_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package validator import ( diff --git a/webhook/validator/pipeline.go b/webhook/validator/pipeline.go index 2c41cfecb..0c3efbcee 100644 --- a/webhook/validator/pipeline.go +++ b/webhook/validator/pipeline.go @@ -1,13 +1,30 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package validator import ( "context" + admissionv1 "k8s.io/api/admission/v1" + "k8s.io/client-go/kubernetes" + dfv1 "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" "github.com/numaproj/numaflow/pkg/client/clientset/versioned/typed/numaflow/v1alpha1" pipelinecontroller "github.com/numaproj/numaflow/pkg/reconciler/pipeline" - admissionv1 "k8s.io/api/admission/v1" - "k8s.io/client-go/kubernetes" ) type pipelineValidator struct { diff --git a/webhook/validator/pipeline_test.go b/webhook/validator/pipeline_test.go index b0bc542e5..966dec3a5 100644 --- a/webhook/validator/pipeline_test.go +++ b/webhook/validator/pipeline_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package validator import ( diff --git a/webhook/validator/validator.go b/webhook/validator/validator.go index d1c3b2f2f..a54917144 100644 --- a/webhook/validator/validator.go +++ b/webhook/validator/validator.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package validator import ( @@ -5,14 +21,14 @@ import ( "encoding/json" "fmt" - dfv1 "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" - "github.com/numaproj/numaflow/pkg/client/clientset/versioned/typed/numaflow/v1alpha1" - "github.com/numaproj/numaflow/pkg/shared/logging" + admissionv1 "k8s.io/api/admission/v1" + apierrors "k8s.io/apimachinery/pkg/api/errors" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" "k8s.io/client-go/kubernetes" - admissionv1 "k8s.io/api/admission/v1" - apierrors "k8s.io/apimachinery/pkg/api/errors" + dfv1 "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" + "github.com/numaproj/numaflow/pkg/client/clientset/versioned/typed/numaflow/v1alpha1" + "github.com/numaproj/numaflow/pkg/shared/logging" ) type Validator interface { @@ -61,7 +77,7 @@ func GetValidator(ctx context.Context, client kubernetes.Interface, ISBSVCClient } return NewPipelineValidator(client, PipelineClient, old, new), nil default: - return nil, fmt.Errorf("Unrecognized kind: %v", kind) + return nil, fmt.Errorf("unrecognized kind: %v", kind) } } diff --git a/webhook/validator/validator_test.go b/webhook/validator/validator_test.go index 181b76742..030fcd8c5 100644 --- a/webhook/validator/validator_test.go +++ b/webhook/validator/validator_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package validator import ( diff --git a/webhook/webhook.go b/webhook/webhook.go index edf43321d..9937826e3 100644 --- a/webhook/webhook.go +++ b/webhook/webhook.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package webhook import ( @@ -13,10 +29,6 @@ import ( "time" "github.com/go-openapi/inflect" - "github.com/numaproj/numaflow/pkg/client/clientset/versioned/typed/numaflow/v1alpha1" - "github.com/numaproj/numaflow/pkg/shared/logging" - commontls "github.com/numaproj/numaflow/pkg/shared/tls" - "github.com/numaproj/numaflow/webhook/validator" "go.uber.org/zap" admissionv1 "k8s.io/api/admission/v1" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" @@ -29,6 +41,11 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" "k8s.io/client-go/kubernetes" clientadmissionregistrationv1 "k8s.io/client-go/kubernetes/typed/admissionregistration/v1" + + "github.com/numaproj/numaflow/pkg/client/clientset/versioned/typed/numaflow/v1alpha1" + "github.com/numaproj/numaflow/pkg/shared/logging" + commontls "github.com/numaproj/numaflow/pkg/shared/tls" + "github.com/numaproj/numaflow/webhook/validator" ) const ( @@ -267,7 +284,7 @@ func (ac *AdmissionController) generateSecret(ctx context.Context) (*corev1.Secr } deployment, err := ac.Client.AppsV1().Deployments(ac.Options.Namespace).Get(ctx, ac.Options.DeploymentName, metav1.GetOptions{}) if err != nil { - return nil, fmt.Errorf("Failed to fetch webhook deployment, %w", err) + return nil, fmt.Errorf("failed to fetch webhook deployment, %w", err) } deploymentRef := metav1.NewControllerRef(deployment, appsv1.SchemeGroupVersion.WithKind("Deployment")) secret := &corev1.Secret{ diff --git a/webhook/webhook_test.go b/webhook/webhook_test.go index 02516f14f..e4435566f 100644 --- a/webhook/webhook_test.go +++ b/webhook/webhook_test.go @@ -1,3 +1,19 @@ +/* +Copyright 2022 The Numaproj Authors. + +Licensed under the Apache License, Version 2.0 (the "License"); +you may not use this file except in compliance with the License. +You may obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + +Unless required by applicable law or agreed to in writing, software +distributed under the License is distributed on an "AS IS" BASIS, +WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +See the License for the specific language governing permissions and +limitations under the License. +*/ + package webhook import ( @@ -7,8 +23,6 @@ import ( "net" "testing" - dfv1 "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" - "github.com/numaproj/numaflow/pkg/shared/logging" "github.com/stretchr/testify/assert" admissionv1 "k8s.io/api/admission/v1" admissionregistrationv1 "k8s.io/api/admissionregistration/v1" @@ -18,6 +32,9 @@ import ( "k8s.io/apimachinery/pkg/runtime/schema" fakeClient "k8s.io/client-go/kubernetes/fake" "sigs.k8s.io/controller-runtime/pkg/manager/signals" + + dfv1 "github.com/numaproj/numaflow/pkg/apis/numaflow/v1alpha1" + "github.com/numaproj/numaflow/pkg/shared/logging" ) func fakeOptions() Options {