diff --git a/.ci/clusters/values.yaml b/.ci/clusters/values.yaml new file mode 100644 index 00000000..42a4391f --- /dev/null +++ b/.ci/clusters/values.yaml @@ -0,0 +1,133 @@ +# Copyright 2022 StreamNative +# +# 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. + +## deployed withh emptyDir +volumes: + persistence: false + +# disabled AntiAffinity +affinity: + anti_affinity: false + +# disable auto recovery +components: + autorecovery: false + pulsar_manager: false + sql_worker: false + proxy: false + toolset: false + +## disable monitoring stack +monitoring: + # monitoring - prometheus + prometheus: false + # monitoring - grafana + grafana: false + # monitoring - node_exporter + node_exporter: false + # alerting - alert-manager + alert_manager: false + # monitoring - loki + loki: false + # monitoring - datadog + datadog: false + +images: + zookeeper: + repository: streamnative/sn-platform + tag: 2.10.4.3 + bookie: + repository: streamnative/sn-platform + tag: 2.10.4.3 + broker: + repository: streamnative/sn-platform + tag: 2.10.4.3 + functions: + repository: streamnative/sn-platform + tag: 2.10.4.3 + +zookeeper: + replicaCount: 1 + resources: + requests: + memory: 256Mi + cpu: 10m + +bookkeeper: + replicaCount: 1 + metadata: + image: + repository: streamnative/sn-platform + tag: 2.10.4.3 + resources: + requests: + memory: 256Mi + cpu: 10m + configData: + PULSAR_PREFIX_autoRecoveryDaemonEnabled: "false" + PULSAR_PREFIX_dlog.bkcEnsembleSize: "1" + PULSAR_PREFIX_dlog.bkcWriteQuorumSize: "1" + PULSAR_PREFIX_dlog.bkcAckQuorumSize: "1" + # `BOOKIE_MEM` is used for `bookie shell` + BOOKIE_MEM: > + -Xms128m + -Xmx256m + -XX:MaxDirectMemorySize=256m + # we use `bin/pulsar` for starting bookie daemons + PULSAR_MEM: > + -Xms128m + -Xmx256m + -XX:MaxDirectMemorySize=256m + PULSAR_GC: > + -XX:+UseG1GC + -XX:MaxGCPauseMillis=10 + -XX:+ParallelRefProcEnabled + -XX:+UnlockExperimentalVMOptions + -XX:+AggressiveOpts + -XX:+DoEscapeAnalysis + -XX:ParallelGCThreads=4 + -XX:ConcGCThreads=4 + -XX:G1NewSizePercent=50 + -XX:+DisableExplicitGC + -XX:-ResizePLAB + -XX:+ExitOnOutOfMemoryError + -XX:+PerfDisableSharedMem + +pulsar_metadata: + image: + repository: streamnative/sn-platform + tag: 2.10.4.3 + +broker: + replicaCount: 1 + configData: + ## Enable `autoSkipNonRecoverableData` since bookkeeper is running + ## without persistence + autoSkipNonRecoverableData: "true" + # storage settings + managedLedgerDefaultEnsembleSize: "1" + managedLedgerDefaultWriteQuorum: "1" + managedLedgerDefaultAckQuorum: "1" + enablePackagesManagement: "true" + PULSAR_PREFIX_enablePackagesManagement: "true" + resources: + requests: + memory: 256Mi + cpu: 10m + +functions: + functionState: false + useDedicatedRunner: false + configData: + narExtractionDirectory: /pulsar/data diff --git a/.github/workflows/chart-test.yml b/.github/workflows/chart-test.yml index 943cbf88..fd06e0de 100644 --- a/.github/workflows/chart-test.yml +++ b/.github/workflows/chart-test.yml @@ -42,6 +42,10 @@ jobs: diff config/crd/bases/resource.streamnative.io_pulsarnamespaces.yaml charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarnamespaces.yaml && \ diff config/crd/bases/resource.streamnative.io_pulsarpermissions.yaml charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarpermissions.yaml && \ diff config/crd/bases/resource.streamnative.io_pulsartenants.yaml charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsartenants.yaml && \ + diff config/crd/bases/resource.streamnative.io_pulsarfunctions.yaml charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarfunctions.yaml && \ + diff config/crd/bases/resource.streamnative.io_pulsarsinks.yaml charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarsinks.yaml && \ + diff config/crd/bases/resource.streamnative.io_pulsarsources.yaml charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarsources.yaml && \ + diff config/crd/bases/resource.streamnative.io_pulsarpackages.yaml charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarpackages.yaml && \ diff config/crd/bases/resource.streamnative.io_pulsartopics.yaml charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsartopics.yaml - name: Set up Helm diff --git a/.github/workflows/e2e_test.yml b/.github/workflows/e2e_test.yml index 0a387a95..7e6255ca 100644 --- a/.github/workflows/e2e_test.yml +++ b/.github/workflows/e2e_test.yml @@ -32,7 +32,7 @@ jobs: ALWAYS_UPDATE_PULSAR_RESOURCE: ${{ matrix.alwaysUpdatePulsar }} GOPRIVATE: github.com/streamnative ACCESS_TOKEN: ${{ secrets.ACCESS_TOKEN }} - IMAGE: apachepulsar/pulsar:latest + IMAGE: streamnative/sn-platform:2.10.4.3 WATCH_CERT_MANAGER_CRDS: "false" steps: - name: clean disk @@ -54,6 +54,13 @@ jobs: run: | git config --global url."https://${ACCESS_TOKEN}:@github.com/".insteadOf "https://github.com/" + - name: Login to DockerHub + uses: docker/login-action@v2 + with: + registry: docker.io + username: ${{ secrets.DOCKER_USER }} + password: ${{ secrets.DOCKER_PASSWORD }} + - name: Set up Ginkgo run: | go install github.com/onsi/ginkgo/ginkgo@latest @@ -64,7 +71,7 @@ jobs: # TODO the k8s version should be configurable - name: Setup K8s cluster run: | - curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.11.1/kind-linux-amd64 + curl -Lo ./kind https://kind.sigs.k8s.io/dl/v0.23.0/kind-linux-amd64 chmod +x ./kind export PATH="$PWD:$PATH" kind version @@ -79,15 +86,21 @@ jobs: df -h - - name: Install Pulsar Operators and sn-platform + - name: Install Pulsar Operators and sn-platform run: | helm repo add streamnative https://charts.streamnative.io helm repo add jetstack https://charts.jetstack.io helm repo update - kubectl create namespace sn-system - helm install pulsar-operators --namespace sn-system streamnative/pulsar-operator - helm install cert-manager --namespace sn-system jetstack/cert-manager --set installCRDs=true - helm install test streamnative/sn-platform --version 1.2.38 --set initialize=true,auth.authentication.enabled=false,auth.authorization.enabled=false,components.toolset=false,components.streamnative_console=false,components.vault=false,components.pulsar_detector=false,monitoring.prometheus=false,monitoring.grafana=false,monitoring.node_exporter=false,monitoring.alert_manager=false,zookeeper.resources.requests.cpu=10m,bookkeeper.resources.requests.cpu=10m,broker.resources.requests.cpu=10m,proxy.resources.requests.cpu=10m + helm install cert-manager jetstack/cert-manager --set installCRDs=true --version v1.8.2 + + rm -rf pulsar-charts/ + git clone --branch pulsar-operator-0.17.10 https://github.com/streamnative/charts.git pulsar-charts + cd pulsar-charts/ + ./scripts/pulsar/prepare_helm_release.sh -n default -k test -c + helm repo add grafana https://grafana.github.io/helm-charts + helm repo update + helm dependency update charts/pulsar + helm install test --set initialize=true --values ../.ci/clusters/values.yaml charts/pulsar df -h - name: Build and Setup Pulsar Resources Operator diff --git a/Makefile b/Makefile index 1f5ba997..94164ea2 100644 --- a/Makefile +++ b/Makefile @@ -54,6 +54,9 @@ IMG ?= controller:latest # ENVTEST_K8S_VERSION refers to the version of kubebuilder assets to be downloaded by envtest binary. ENVTEST_K8S_VERSION = 1.23 +# Architecture to use envtest with +ENVTEST_ARCH ?= amd64 + KUBE_RBAC_PROXY_IMG ?= gcr.io/kubebuilder/kube-rbac-proxy:v0.14.4 REDHAT_SCAN_REGITRY ?= "quay.io" @@ -112,7 +115,7 @@ vet: ## Run go vet against code. .PHONY: test test: manifests generate fmt vet envtest ## Run tests. - KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) -p path)" go test ./... -coverprofile cover.out + KUBEBUILDER_ASSETS="$(shell $(ENVTEST) use $(ENVTEST_K8S_VERSION) --arch=${ENVTEST_ARCH} -p path)" go test ./... -coverprofile cover.out ##@ Build @@ -181,7 +184,7 @@ undeploy: ## Undeploy controller from the K8s cluster specified in ~/.kube/confi CONTROLLER_GEN = $(shell pwd)/bin/controller-gen .PHONY: controller-gen controller-gen: ## Download controller-gen locally if necessary. - $(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.8.0) + $(call go-get-tool,$(CONTROLLER_GEN),sigs.k8s.io/controller-tools/cmd/controller-gen@v0.15.0) KUSTOMIZE = $(shell pwd)/bin/kustomize .PHONY: kustomize @@ -289,7 +292,7 @@ husky: LICENSE_EYE = $(shell pwd)/bin/license-eye .PHONY: license-eye license-eye: ## Download license-eye locally if necessary. https://github.com/apache/skywalking-eyes - $(call go-get-tool,$(LICENSE_EYE),github.com/apache/skywalking-eyes/cmd/license-eye@0.4.0) + $(call go-get-tool,$(LICENSE_EYE),github.com/apache/skywalking-eyes/cmd/license-eye@v0.4.0) ## Check if the specified files have the license header in the config file. .PHONY: license-check diff --git a/README.md b/README.md index f863b463..0ff61ae0 100644 --- a/README.md +++ b/README.md @@ -8,6 +8,10 @@ Currently, the Pulsar Resources Operator provides full lifecycle management for - Namespaces - Topics - Permissions +- Packages +- Functions +- Sinks +- Sources # Installation @@ -98,6 +102,10 @@ In this tutorial, a Kubernetes namespace called `test` is used for examples, whi - [PulsarNamespace](docs/pulsar_namespace.md) - [PulsarTopic](docs/pulsar_topic.md) - [PulsarPermission](docs/pulsar_permission.md) +- [PulsarPackage](docs/pulsar_package.md) +- [PulsarFunction](docs/pulsar_function.md) +- [PulsarSink](docs/pulsar_sink.md) +- [PulsarSource](docs/pulsar_source.md) ## Contributing diff --git a/api/v1alpha1/common.go b/api/v1alpha1/common.go index de7293eb..7e4f19ed 100644 --- a/api/v1alpha1/common.go +++ b/api/v1alpha1/common.go @@ -86,3 +86,52 @@ func IsPulsarResourceReady(instance reconciler.Object) bool { instance.GetGeneration() == observedGeneration && meta.IsStatusConditionTrue(conditions, ConditionReady) } + +// PackageContentRef indicates the package content reference +type PackageContentRef struct { + // +optional + // persistentVolumeTemplate *corev1.PersistentVolumeClaim `json:"persistentVolumeTemplate,omitempty"` + + // +optional + URL string `json:"url,omitempty"` +} + +// Resources indicates the resources for the pulsar functions and connectors +type Resources struct { + CPU string `json:"cpu"` + Disk int64 `json:"disk"` + RAM int64 `json:"ram"` +} + +// ProducerConfig represents the configuration for the producer of the pulsar functions and connectors +type ProducerConfig struct { + MaxPendingMessages int `json:"maxPendingMessages" yaml:"maxPendingMessages"` + MaxPendingMessagesAcrossPartitions int `json:"maxPendingMessagesAcrossPartitions" yaml:"maxPendingMessagesAcrossPartitions"` + + UseThreadLocalProducers bool `json:"useThreadLocalProducers" yaml:"useThreadLocalProducers"` + CryptoConfig *CryptoConfig `json:"cryptoConfig" yaml:"cryptoConfig"` + BatchBuilder string `json:"batchBuilder" yaml:"batchBuilder"` + CompressionType string `json:"compressionType" yaml:"compressionType"` +} + +// ConsumerConfig represents the configuration for the consumer of the pulsar functions and connectors +type ConsumerConfig struct { + SchemaType string `json:"schemaType,omitempty" yaml:"schemaType"` + SerdeClassName string `json:"serdeClassName,omitempty" yaml:"serdeClassName"` + RegexPattern bool `json:"regexPattern,omitempty" yaml:"regexPattern"` + ReceiverQueueSize int `json:"receiverQueueSize,omitempty" yaml:"receiverQueueSize"` + SchemaProperties map[string]string `json:"schemaProperties,omitempty" yaml:"schemaProperties"` + ConsumerProperties map[string]string `json:"consumerProperties,omitempty" yaml:"consumerProperties"` + CryptoConfig *CryptoConfig `json:"cryptoConfig,omitempty" yaml:"cryptoConfig"` + PoolMessages bool `json:"poolMessages,omitempty" yaml:"poolMessages"` +} + +// CryptoConfig represents the configuration for the crypto of the pulsar functions and connectors +type CryptoConfig struct { + CryptoKeyReaderClassName string `json:"cryptoKeyReaderClassName" yaml:"cryptoKeyReaderClassName"` + CryptoKeyReaderConfig map[string]string `json:"cryptoKeyReaderConfig" yaml:"cryptoKeyReaderConfig"` + + EncryptionKeys []string `json:"encryptionKeys" yaml:"encryptionKeys"` + ProducerCryptoFailureAction string `json:"producerCryptoFailureAction" yaml:"producerCryptoFailureAction"` + ConsumerCryptoFailureAction string `json:"consumerCryptoFailureAction" yaml:"consumerCryptoFailureAction"` +} diff --git a/api/v1alpha1/pulsarfunction_types.go b/api/v1alpha1/pulsarfunction_types.go new file mode 100644 index 00000000..2fa8445c --- /dev/null +++ b/api/v1alpha1/pulsarfunction_types.go @@ -0,0 +1,268 @@ +// Copyright 2022 StreamNative +// +// 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 ( + corev1 "k8s.io/api/core/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// PulsarFunctionSpec defines the desired state of PulsarFunction +type PulsarFunctionSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // TimeoutMs is the function timeout in milliseconds + // +optional + TimeoutMs *int64 `json:"timeoutMs,omitempty"` + + // TopicsPattern is the topics pattern that the function subscribes to + // +optional + TopicsPattern *string `json:"topicsPattern,omitempty"` + + // CleanupSubscription is the flag to indicate whether the subscription should be cleaned up when the function is deleted + // +optional + CleanupSubscription bool `json:"cleanupSubscription"` + + // RetainOrdering is the flag to indicate whether the function should retain ordering + // +optional + RetainOrdering bool `json:"retainOrdering"` + + // RetainKeyOrdering is the flag to indicate whether the function should retain key ordering + // +optional + RetainKeyOrdering bool `json:"retainKeyOrdering"` + + // BatchBuilder is the batch builder that the function uses + // +optional + BatchBuilder *string `json:"batchBuilder,omitempty"` + + // ForwardSourceMessageProperty is the flag to indicate whether the function should forward source message properties + // +optional + ForwardSourceMessageProperty bool `json:"forwardSourceMessageProperty"` + + // AutoAck is the flag to indicate whether the function should auto ack + // +optional + AutoAck bool `json:"autoAck"` + + // Parallelism is the parallelism of the function + // +optional + Parallelism int `json:"parallelism,omitempty"` + + // MaxMessageRetries is the max message retries of the function + // +optional + MaxMessageRetries *int `json:"maxMessageRetries,omitempty"` + + // Output is the output of the function + // +optional + Output string `json:"output,omitempty"` + + // ProducerConfig is the producer config of the function + // +optional + ProducerConfig *ProducerConfig `json:"producerConfig,omitempty"` + + // CustomSchemaOutputs is the custom schema outputs of the function + // +optional + CustomSchemaOutputs map[string]string `json:"customSchemaOutputs,omitempty"` + + // OutputSerdeClassName is the output serde class name of the function + // +optional + OutputSerdeClassName string `json:"outputSerdeClassName,omitempty"` + + // LogTopic is the log topic of the function + // +optional + LogTopic string `json:"logTopic,omitempty"` + + // ProcessingGuarantees is the processing guarantees of the function + // +optional + ProcessingGuarantees string `json:"processingGuarantees,omitempty"` + + // OutputSchemaType is the output schema type of the function + // +optional + OutputSchemaType string `json:"outputSchemaType,omitempty"` + + // OutputTypeClassName is the output type class name of the function + // +optional + OutputTypeClassName string `json:"outputTypeClassName,omitempty"` + + // DeadLetterTopic is the dead letter topic of the function + // +optional + DeadLetterTopic string `json:"deadLetterTopic,omitempty"` + + // SubName is the sub name of the function + // +optional + SubName string `json:"subName,omitempty"` + + // Jar is the jar of the function + // +optional + Jar *PackageContentRef `json:"jar,omitempty"` + + // Py is the py of the function + // +optional + Py *PackageContentRef `json:"py,omitempty"` + + // Go is the go of the function + // +optional + Go *PackageContentRef `json:"go,omitempty"` + + // RuntimeFlags is the runtime flags of the function + // +optional + RuntimeFlags string `json:"runtimeFlags,omitempty"` + + // Tenant is the tenant of the function + // +optional + Tenant string `json:"tenant,omitempty"` + + // Namespace is the namespace of the function + // +optional + Namespace string `json:"namespace,omitempty"` + + // Name is the name of the function + // +optional + Name string `json:"name,omitempty"` + + // ClassName is the class name of the function + // +optional + ClassName string `json:"className,omitempty"` + + // Resources is the resources of the function + // +optional + Resources *Resources `json:"resources,omitempty"` + + // WindowConfig is the window config of the function + // +optional + WindowConfig *WindowConfig `json:"windowConfig,omitempty"` + + // Inputs is the inputs of the function + // +optional + Inputs []string `json:"inputs,omitempty"` + + // UserConfig is the user config of the function + // +optional + UserConfig *apiextensionsv1.JSON `json:"userConfig,omitempty"` + + // CustomSerdeInputs is the custom serde inputs of the function + // +optional + CustomSerdeInputs map[string]string `json:"customSerdeInputs,omitempty"` + + // CustomSchemaInputs is the custom schema inputs of the function + // +optional + CustomSchemaInputs map[string]string `json:"customSchemaInputs,omitempty"` + + // InputSpecs is the input specs of the function + // +optional + InputSpecs map[string]ConsumerConfig `json:"inputSpecs,omitempty"` + + // InputTypeClassName is the input type class name of the function + // +optional + InputTypeClassName string `json:"inputTypeClassName,omitempty"` + + // CustomRuntimeOptions is the custom runtime options of the function + // +optional + CustomRuntimeOptions *apiextensionsv1.JSON `json:"customRuntimeOptions,omitempty"` + + // Secrets is the secrets of the function + // +optional + Secrets map[string]SecretKeyRef `json:"secrets,omitempty"` + + // MaxPendingAsyncRequests is the max pending async requests of the function + // +optional + MaxPendingAsyncRequests int `json:"maxPendingAsyncRequests,omitempty"` + + // ExposePulsarAdminClientEnabled is the flag to indicate whether the function should expose pulsar admin client + // +optional + ExposePulsarAdminClientEnabled bool `json:"exposePulsarAdminClientEnabled"` + + // SkipToLatest is the flag to indicate whether the function should skip to latest + // +optional + SkipToLatest bool `json:"skipToLatest"` + + // SubscriptionPosition is the subscription position of the function + // +optional + SubscriptionPosition string `json:"subscriptionPosition,omitempty"` + + // ConnectionRef is the reference to the PulsarConnection resource + ConnectionRef corev1.LocalObjectReference `json:"connectionRef"` + + // +kubebuilder:validation:Enum=CleanUpAfterDeletion;KeepAfterDeletion + // +optional + LifecyclePolicy PulsarResourceLifeCyclePolicy `json:"lifecyclePolicy,omitempty"` +} + +// WindowConfig defines the window config of the function +type WindowConfig struct { + WindowLengthCount *int `json:"windowLengthCount" yaml:"windowLengthCount"` + WindowLengthDurationMs *int64 `json:"windowLengthDurationMs" yaml:"windowLengthDurationMs"` + SlidingIntervalCount *int `json:"slidingIntervalCount" yaml:"slidingIntervalCount"` + SlidingIntervalDurationMs *int64 `json:"slidingIntervalDurationMs" yaml:"slidingIntervalDurationMs"` + LateDataTopic *string `json:"lateDataTopic" yaml:"lateDataTopic"` + MaxLagMs *int64 `json:"maxLagMs" yaml:"maxLagMs"` + WatermarkEmitIntervalMs *int64 `json:"watermarkEmitIntervalMs" yaml:"watermarkEmitIntervalMs"` + TimestampExtractorClassName *string `json:"timestampExtractorClassName" yaml:"timestampExtractorClassName"` + ActualWindowFunctionClassName *string `json:"actualWindowFunctionClassName" yaml:"actualWindowFunctionClassName"` + ProcessingGuarantees *string `json:"processingGuarantees" yaml:"processingGuarantees"` +} + +// PulsarFunctionStatus defines the observed state of PulsarFunction +type PulsarFunctionStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // ObservedGeneration is the most recent generation observed for this resource. + // It corresponds to the metadata generation, which is updated on mutation by the API Server. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Represents the observations of a connection's current state. + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status +//+kubebuilder:resource:categories=pulsar;pulsarres,shortName=pfunction +//+kubebuilder:printcolumn:name="RESOURCE_NAME",type=string,JSONPath=`.spec.name` +//+kubebuilder:printcolumn:name="GENERATION",type=string,JSONPath=`.metadata.generation` +//+kubebuilder:printcolumn:name="OBSERVED_GENERATION",type=string,JSONPath=`.status.observedGeneration` +//+kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status` + +// PulsarFunction is the Schema for the pulsar functions API +type PulsarFunction struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec PulsarFunctionSpec `json:"spec,omitempty"` + Status PulsarFunctionStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// PulsarFunctionList contains a list of PulsarFunction +type PulsarFunctionList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []PulsarFunction `json:"items"` +} + +func init() { + SchemeBuilder.Register(&PulsarFunction{}, &PulsarFunctionList{}) +} diff --git a/api/v1alpha1/pulsarpackage_types.go b/api/v1alpha1/pulsarpackage_types.go new file mode 100644 index 00000000..d975985b --- /dev/null +++ b/api/v1alpha1/pulsarpackage_types.go @@ -0,0 +1,102 @@ +// Copyright 2022 StreamNative +// +// 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 ( + corev1 "k8s.io/api/core/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// PulsarPackageSpec defines the desired state of PulsarPackage +type PulsarPackageSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // PackageURL is the Pulsar Package URL, in format of type://tenant/namespace/package@version + // +kubebuilder:validation:Required + PackageURL string `json:"packageURL"` + + // FileURL is the download-able URL of the package from http or https protocol + // +kubebuilder:validation:Required + FileURL string `json:"fileURL"` + + // ConnectionRef is the reference to the PulsarConnection resource + ConnectionRef corev1.LocalObjectReference `json:"connectionRef"` + + // +optional + Description string `json:"description,omitempty"` + + // +optional + Contact string `json:"contact,omitempty"` + + // +optional + Properties map[string]string `json:"properties,omitempty"` + + // +kubebuilder:validation:Enum=CleanUpAfterDeletion;KeepAfterDeletion + // +optional + LifecyclePolicy PulsarResourceLifeCyclePolicy `json:"lifecyclePolicy,omitempty"` +} + +// PulsarPackageStatus defines the observed state of PulsarPackage +type PulsarPackageStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // ObservedGeneration is the most recent generation observed for this resource. + // It corresponds to the metadata generation, which is updated on mutation by the API Server. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Represents the observations of a connection's current state. + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status +//+kubebuilder:resource:categories=pulsar;pulsarres,shortName=ppackage +//+kubebuilder:printcolumn:name="RESOURCE_NAME",type=string,JSONPath=`.spec.name` +//+kubebuilder:printcolumn:name="GENERATION",type=string,JSONPath=`.metadata.generation` +//+kubebuilder:printcolumn:name="OBSERVED_GENERATION",type=string,JSONPath=`.status.observedGeneration` +//+kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status` + +// PulsarPackage is the Schema for the pulsar package management service's package API +type PulsarPackage struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec PulsarPackageSpec `json:"spec,omitempty"` + Status PulsarPackageStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// PulsarPackageList contains a list of PulsarPackage +type PulsarPackageList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []PulsarPackage `json:"items"` +} + +func init() { + SchemeBuilder.Register(&PulsarPackage{}, &PulsarPackageList{}) +} diff --git a/api/v1alpha1/pulsarsink_types.go b/api/v1alpha1/pulsarsink_types.go new file mode 100644 index 00000000..603e8e39 --- /dev/null +++ b/api/v1alpha1/pulsarsink_types.go @@ -0,0 +1,214 @@ +// Copyright 2022 StreamNative +// +// 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 ( + corev1 "k8s.io/api/core/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// PulsarSinkSpec defines the desired state of PulsarSink +type PulsarSinkSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // TopicsPattern is the pattern of topics to consume from Pulsar + // +optional + TopicsPattern *string `json:"topicsPattern,omitempty"` + + // Resources is the resource requirements for the PulsarSink + // +optional + Resources *Resources `json:"resources,omitempty"` + + // TimeoutMs is the timeout in milliseconds for the PulsarSink + // +optional + TimeoutMs *int64 `json:"timeoutMs,omitempty"` + + // CleanupSubscription is the flag to enable or disable the cleanup of subscription + // +optional + CleanupSubscription bool `json:"cleanupSubscription,omitempty"` + + // RetainOrdering is the flag to enable or disable the retain ordering + // +optional + RetainOrdering bool `json:"retainOrdering,omitempty"` + + // RetainKeyOrdering is the flag to enable or disable the retain key ordering + // +optional + RetainKeyOrdering bool `json:"retainKeyOrdering,omitempty"` + + // AutoAck is the flag to enable or disable the auto ack + // +optional + AutoAck bool `json:"autoAck,omitempty"` + + // Parallelism is the parallelism of the PulsarSink + // +optional + Parallelism int `json:"parallelism,omitempty"` + + // Tenant is the tenant of the PulsarSink + // +optional + Tenant string `json:"tenant,omitempty"` + + // Namespace is the namespace of the PulsarSink + // +optional + Namespace string `json:"namespace,omitempty"` + + // Name is the name of the PulsarSink + // +optional + Name string `json:"name,omitempty"` + + // ClassName is the class name of the PulsarSink + // +optional + ClassName string `json:"className,omitempty"` + + // SinkType is the type of the PulsarSink + // +optional + SinkType string `json:"sinkType,omitempty"` + + // Archive is the archive of the PulsarSink + // +optional + Archive *PackageContentRef `json:"archive,omitempty"` + + // ProcessingGuarantees is the processing guarantees of the PulsarSink + // +optional + ProcessingGuarantees string `json:"processingGuarantees,omitempty"` + + // SourceSubscriptionName is the source subscription name of the PulsarSink + // +optional + SourceSubscriptionName string `json:"sourceSubscriptionName,omitempty"` + + // SourceSubscriptionPosition is the source subscription position of the PulsarSink + // +optional + SourceSubscriptionPosition string `json:"sourceSubscriptionPosition,omitempty"` + + // RuntimeFlags is the runtime flags of the PulsarSink + // +optional + RuntimeFlags string `json:"runtimeFlags,omitempty"` + + // Inputs is the list of inputs of the PulsarSink + // +optional + Inputs []string `json:"inputs,omitempty"` + + // TopicToSerdeClassName is the map of topic to serde class name of the PulsarSink + // +optional + TopicToSerdeClassName map[string]string `json:"topicToSerdeClassName,omitempty"` + + // TopicToSchemaType is the map of topic to schema type of the PulsarSink + // +optional + TopicToSchemaType map[string]string `json:"topicToSchemaType,omitempty"` + + // InputSpecs is the map of input specs of the PulsarSink + // +optional + InputSpecs map[string]ConsumerConfig `json:"inputSpecs,omitempty"` + + // Configs is the map of configs of the PulsarSink + // +optional + Configs *apiextensionsv1.JSON `json:"configs,omitempty"` + + // TopicToSchemaProperties is the map of topic to schema properties of the PulsarSink + // +optional + TopicToSchemaProperties map[string]string `json:"topicToSchemaProperties,omitempty"` + + // CustomRuntimeOptions is the custom runtime options of the PulsarSink + // +optional + CustomRuntimeOptions *apiextensionsv1.JSON `json:"customRuntimeOptions,omitempty"` + + // Secrets is the map of secrets of the PulsarSink + // +optional + Secrets map[string]SecretKeyRef `json:"secrets,omitempty"` + + // MaxMessageRetries is the max message retries of the PulsarSink + // +optional + MaxMessageRetries int `json:"maxMessageRetries,omitempty"` + + // DeadLetterTopic is the dead letter topic of the PulsarSink + // +optional + DeadLetterTopic string `json:"deadLetterTopic,omitempty"` + + // NegativeAckRedeliveryDelayMs is the negative ack redelivery delay in milliseconds of the PulsarSink + // +optional + NegativeAckRedeliveryDelayMs int64 `json:"negativeAckRedeliveryDelayMs,omitempty"` + + // TransformFunction is the transform function of the PulsarSink + // +optional + TransformFunction string `json:"transformFunction,omitempty"` + + // TransformFunctionClassName is the transform function class name of the PulsarSink + // +optional + TransformFunctionClassName string `json:"transformFunctionClassName,omitempty"` + + // TransformFunctionConfig is the transform function config of the PulsarSink + // +optional + TransformFunctionConfig string `json:"transformFunctionConfig,omitempty"` + + // ConnectionRef is the reference to the PulsarConnection resource + ConnectionRef corev1.LocalObjectReference `json:"connectionRef"` + + // +kubebuilder:validation:Enum=CleanUpAfterDeletion;KeepAfterDeletion + // +optional + LifecyclePolicy PulsarResourceLifeCyclePolicy `json:"lifecyclePolicy,omitempty"` +} + +// PulsarSinkStatus defines the observed state of PulsarSink +type PulsarSinkStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // ObservedGeneration is the most recent generation observed for this resource. + // It corresponds to the metadata generation, which is updated on mutation by the API Server. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Represents the observations of a connection's current state. + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status +//+kubebuilder:resource:categories=pulsar;pulsarres,shortName=psink +//+kubebuilder:printcolumn:name="RESOURCE_NAME",type=string,JSONPath=`.spec.name` +//+kubebuilder:printcolumn:name="GENERATION",type=string,JSONPath=`.metadata.generation` +//+kubebuilder:printcolumn:name="OBSERVED_GENERATION",type=string,JSONPath=`.status.observedGeneration` +//+kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status` + +// PulsarSink is the Schema for the pulsar functions API +type PulsarSink struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec PulsarSinkSpec `json:"spec,omitempty"` + Status PulsarSinkStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// PulsarSinkList contains a list of PulsarSink +type PulsarSinkList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []PulsarSink `json:"items"` +} + +func init() { + SchemeBuilder.Register(&PulsarSink{}, &PulsarSinkList{}) +} diff --git a/api/v1alpha1/pulsarsource_types.go b/api/v1alpha1/pulsarsource_types.go new file mode 100644 index 00000000..cdcb61c1 --- /dev/null +++ b/api/v1alpha1/pulsarsource_types.go @@ -0,0 +1,165 @@ +// Copyright 2022 StreamNative +// +// 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 ( + corev1 "k8s.io/api/core/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" +) + +// EDIT THIS FILE! THIS IS SCAFFOLDING FOR YOU TO OWN! +// NOTE: json tags are required. Any new fields you add must have json tags for the fields to be serialized. + +// PulsarSourceSpec defines the desired state of PulsarSource +type PulsarSourceSpec struct { + // INSERT ADDITIONAL SPEC FIELDS - desired state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // Tenant is the tenant of the PulsarSource + // +optional + Tenant string `json:"tenant,omitempty"` + + // Namespace is the namespace of the PulsarSource + // +optional + Namespace string `json:"namespace,omitempty"` + + // Name is the name of the PulsarSource + // +optional + Name string `json:"name,omitempty"` + + // ClassName is the class name of the + // +optional + ClassName string `json:"className,omitempty"` + + // ProducerConfig is the producer config of the PulsarSource + // +optional + ProducerConfig *ProducerConfig `json:"producerConfig,omitempty"` + + // TopicName is the topic name of the PulsarSource + // +optional + TopicName string `json:"topicName,omitempty"` + + // SerdeClassName is the serde class name of the PulsarSource + // +optional + SerdeClassName string `json:"serdeClassName,omitempty"` + + // SchemaType is the schema type of the PulsarSource + // +optional + SchemaType string `json:"schemaType,omitempty"` + + // Configs is the map of configs of the PulsarSource + // +optional + Configs *apiextensionsv1.JSON `json:"configs,omitempty"` + + // Secrets is the map of secrets of the PulsarSource + // +optional + Secrets map[string]SecretKeyRef `json:"secrets,omitempty"` + + // Parallelism is the parallelism of the PulsarSource + // +optional + Parallelism int `json:"parallelism,omitempty"` + + // ProcessingGuarantees is the processing guarantees of the PulsarSource + // +optional + ProcessingGuarantees string `json:"processingGuarantees,omitempty"` + + // Resources is the resources of the PulsarSource + // +optional + Resources *Resources `json:"resources,omitempty"` + + // Archive is the archive of the PulsarSource + // +optional + Archive *PackageContentRef `json:"archive,omitempty"` + + // RuntimeFlags is the runtime flags of the PulsarSource + // +optional + RuntimeFlags string `json:"runtimeFlags,omitempty"` + + // CustomRuntimeOptions is the custom runtime options of the PulsarSource + // +optional + CustomRuntimeOptions *apiextensionsv1.JSON `json:"customRuntimeOptions,omitempty"` + + // BatchSourceConfig is the batch source config of the PulsarSource + // +optional + BatchSourceConfig *BatchSourceConfig `json:"batchSourceConfig,omitempty"` + + // BatchBuilder is the batch builder of the PulsarSource + // +optional + BatchBuilder string `json:"batchBuilder,omitempty"` + + // ConnectionRef is the reference to the PulsarConnection resource + ConnectionRef corev1.LocalObjectReference `json:"connectionRef"` + + // +kubebuilder:validation:Enum=CleanUpAfterDeletion;KeepAfterDeletion + // +optional + LifecyclePolicy PulsarResourceLifeCyclePolicy `json:"lifecyclePolicy,omitempty"` +} + +// BatchSourceConfig represents the batch source config of the PulsarSource +type BatchSourceConfig struct { + DiscoveryTriggererClassName string `json:"discoveryTriggererClassName" yaml:"discoveryTriggererClassName"` + + DiscoveryTriggererConfig *apiextensionsv1.JSON `json:"discoveryTriggererConfig" yaml:"discoveryTriggererConfig"` +} + +// PulsarSourceStatus defines the observed state of PulsarSource +type PulsarSourceStatus struct { + // INSERT ADDITIONAL STATUS FIELD - define observed state of cluster + // Important: Run "make" to regenerate code after modifying this file + + // ObservedGeneration is the most recent generation observed for this resource. + // It corresponds to the metadata generation, which is updated on mutation by the API Server. + // +optional + ObservedGeneration int64 `json:"observedGeneration,omitempty"` + + // Represents the observations of a connection's current state. + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + // +optional + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type"` +} + +//+kubebuilder:object:root=true +//+kubebuilder:subresource:status +//+kubebuilder:resource:categories=pulsar;pulsarres,shortName=psource +//+kubebuilder:printcolumn:name="RESOURCE_NAME",type=string,JSONPath=`.spec.name` +//+kubebuilder:printcolumn:name="GENERATION",type=string,JSONPath=`.metadata.generation` +//+kubebuilder:printcolumn:name="OBSERVED_GENERATION",type=string,JSONPath=`.status.observedGeneration` +//+kubebuilder:printcolumn:name="READY",type=string,JSONPath=`.status.conditions[?(@.type=="Ready")].status` + +// PulsarSource is the Schema for the pulsar functions API +type PulsarSource struct { + metav1.TypeMeta `json:",inline"` + metav1.ObjectMeta `json:"metadata,omitempty"` + + Spec PulsarSourceSpec `json:"spec,omitempty"` + Status PulsarSourceStatus `json:"status,omitempty"` +} + +//+kubebuilder:object:root=true + +// PulsarSourceList contains a list of PulsarSource +type PulsarSourceList struct { + metav1.TypeMeta `json:",inline"` + metav1.ListMeta `json:"metadata,omitempty"` + Items []PulsarSource `json:"items"` +} + +func init() { + SchemeBuilder.Register(&PulsarSource{}, &PulsarSourceList{}) +} diff --git a/api/v1alpha1/zz_generated.deepcopy.go b/api/v1alpha1/zz_generated.deepcopy.go index e3f2ed08..9990511c 100644 --- a/api/v1alpha1/zz_generated.deepcopy.go +++ b/api/v1alpha1/zz_generated.deepcopy.go @@ -13,7 +13,6 @@ // limitations under the License. //go:build !ignore_autogenerated -// +build !ignore_autogenerated // Code generated by controller-gen. DO NOT EDIT. @@ -22,10 +21,31 @@ package v1alpha1 import ( "github.com/streamnative/pulsar-resources-operator/pkg/utils" corev1 "k8s.io/api/core/v1" - v1 "k8s.io/apimachinery/pkg/apis/meta/v1" + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" + "k8s.io/apimachinery/pkg/apis/meta/v1" runtime "k8s.io/apimachinery/pkg/runtime" ) +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *BatchSourceConfig) DeepCopyInto(out *BatchSourceConfig) { + *out = *in + if in.DiscoveryTriggererConfig != nil { + in, out := &in.DiscoveryTriggererConfig, &out.DiscoveryTriggererConfig + *out = new(apiextensionsv1.JSON) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new BatchSourceConfig. +func (in *BatchSourceConfig) DeepCopy() *BatchSourceConfig { + if in == nil { + return nil + } + out := new(BatchSourceConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *ClusterInfo) DeepCopyInto(out *ClusterInfo) { *out = *in @@ -42,6 +62,102 @@ func (in *ClusterInfo) DeepCopy() *ClusterInfo { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ConsumerConfig) DeepCopyInto(out *ConsumerConfig) { + *out = *in + if in.SchemaProperties != nil { + in, out := &in.SchemaProperties, &out.SchemaProperties + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.ConsumerProperties != nil { + in, out := &in.ConsumerProperties, &out.ConsumerProperties + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.CryptoConfig != nil { + in, out := &in.CryptoConfig, &out.CryptoConfig + *out = new(CryptoConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ConsumerConfig. +func (in *ConsumerConfig) DeepCopy() *ConsumerConfig { + if in == nil { + return nil + } + out := new(ConsumerConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *CryptoConfig) DeepCopyInto(out *CryptoConfig) { + *out = *in + if in.CryptoKeyReaderConfig != nil { + in, out := &in.CryptoKeyReaderConfig, &out.CryptoKeyReaderConfig + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.EncryptionKeys != nil { + in, out := &in.EncryptionKeys, &out.EncryptionKeys + *out = make([]string, len(*in)) + copy(*out, *in) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new CryptoConfig. +func (in *CryptoConfig) DeepCopy() *CryptoConfig { + if in == nil { + return nil + } + out := new(CryptoConfig) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PackageContentRef) DeepCopyInto(out *PackageContentRef) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PackageContentRef. +func (in *PackageContentRef) DeepCopy() *PackageContentRef { + if in == nil { + return nil + } + out := new(PackageContentRef) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *ProducerConfig) DeepCopyInto(out *ProducerConfig) { + *out = *in + if in.CryptoConfig != nil { + in, out := &in.CryptoConfig, &out.CryptoConfig + *out = new(CryptoConfig) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new ProducerConfig. +func (in *ProducerConfig) DeepCopy() *ProducerConfig { + if in == nil { + return nil + } + out := new(ProducerConfig) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *PulsarAuthentication) DeepCopyInto(out *PulsarAuthentication) { *out = *in @@ -111,31 +227,590 @@ func (in *PulsarConnection) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarConnectionList) DeepCopyInto(out *PulsarConnectionList) { +func (in *PulsarConnectionList) DeepCopyInto(out *PulsarConnectionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PulsarConnection, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarConnectionList. +func (in *PulsarConnectionList) DeepCopy() *PulsarConnectionList { + if in == nil { + return nil + } + out := new(PulsarConnectionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PulsarConnectionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarConnectionSpec) DeepCopyInto(out *PulsarConnectionSpec) { + *out = *in + if in.Authentication != nil { + in, out := &in.Authentication, &out.Authentication + *out = new(PulsarAuthentication) + (*in).DeepCopyInto(*out) + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarConnectionSpec. +func (in *PulsarConnectionSpec) DeepCopy() *PulsarConnectionSpec { + if in == nil { + return nil + } + out := new(PulsarConnectionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarConnectionStatus) DeepCopyInto(out *PulsarConnectionStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarConnectionStatus. +func (in *PulsarConnectionStatus) DeepCopy() *PulsarConnectionStatus { + if in == nil { + return nil + } + out := new(PulsarConnectionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarFunction) DeepCopyInto(out *PulsarFunction) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarFunction. +func (in *PulsarFunction) DeepCopy() *PulsarFunction { + if in == nil { + return nil + } + out := new(PulsarFunction) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PulsarFunction) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarFunctionList) DeepCopyInto(out *PulsarFunctionList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PulsarFunction, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarFunctionList. +func (in *PulsarFunctionList) DeepCopy() *PulsarFunctionList { + if in == nil { + return nil + } + out := new(PulsarFunctionList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PulsarFunctionList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarFunctionSpec) DeepCopyInto(out *PulsarFunctionSpec) { + *out = *in + if in.TimeoutMs != nil { + in, out := &in.TimeoutMs, &out.TimeoutMs + *out = new(int64) + **out = **in + } + if in.TopicsPattern != nil { + in, out := &in.TopicsPattern, &out.TopicsPattern + *out = new(string) + **out = **in + } + if in.BatchBuilder != nil { + in, out := &in.BatchBuilder, &out.BatchBuilder + *out = new(string) + **out = **in + } + if in.MaxMessageRetries != nil { + in, out := &in.MaxMessageRetries, &out.MaxMessageRetries + *out = new(int) + **out = **in + } + if in.ProducerConfig != nil { + in, out := &in.ProducerConfig, &out.ProducerConfig + *out = new(ProducerConfig) + (*in).DeepCopyInto(*out) + } + if in.CustomSchemaOutputs != nil { + in, out := &in.CustomSchemaOutputs, &out.CustomSchemaOutputs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Jar != nil { + in, out := &in.Jar, &out.Jar + *out = new(PackageContentRef) + **out = **in + } + if in.Py != nil { + in, out := &in.Py, &out.Py + *out = new(PackageContentRef) + **out = **in + } + if in.Go != nil { + in, out := &in.Go, &out.Go + *out = new(PackageContentRef) + **out = **in + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(Resources) + **out = **in + } + if in.WindowConfig != nil { + in, out := &in.WindowConfig, &out.WindowConfig + *out = new(WindowConfig) + (*in).DeepCopyInto(*out) + } + if in.Inputs != nil { + in, out := &in.Inputs, &out.Inputs + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.UserConfig != nil { + in, out := &in.UserConfig, &out.UserConfig + *out = new(apiextensionsv1.JSON) + (*in).DeepCopyInto(*out) + } + if in.CustomSerdeInputs != nil { + in, out := &in.CustomSerdeInputs, &out.CustomSerdeInputs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.CustomSchemaInputs != nil { + in, out := &in.CustomSchemaInputs, &out.CustomSchemaInputs + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.InputSpecs != nil { + in, out := &in.InputSpecs, &out.InputSpecs + *out = make(map[string]ConsumerConfig, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } + } + if in.CustomRuntimeOptions != nil { + in, out := &in.CustomRuntimeOptions, &out.CustomRuntimeOptions + *out = new(apiextensionsv1.JSON) + (*in).DeepCopyInto(*out) + } + if in.Secrets != nil { + in, out := &in.Secrets, &out.Secrets + *out = make(map[string]SecretKeyRef, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + out.ConnectionRef = in.ConnectionRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarFunctionSpec. +func (in *PulsarFunctionSpec) DeepCopy() *PulsarFunctionSpec { + if in == nil { + return nil + } + out := new(PulsarFunctionSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarFunctionStatus) DeepCopyInto(out *PulsarFunctionStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarFunctionStatus. +func (in *PulsarFunctionStatus) DeepCopy() *PulsarFunctionStatus { + if in == nil { + return nil + } + out := new(PulsarFunctionStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarGeoReplication) DeepCopyInto(out *PulsarGeoReplication) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + out.Spec = in.Spec + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarGeoReplication. +func (in *PulsarGeoReplication) DeepCopy() *PulsarGeoReplication { + if in == nil { + return nil + } + out := new(PulsarGeoReplication) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PulsarGeoReplication) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarGeoReplicationList) DeepCopyInto(out *PulsarGeoReplicationList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PulsarGeoReplication, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarGeoReplicationList. +func (in *PulsarGeoReplicationList) DeepCopy() *PulsarGeoReplicationList { + if in == nil { + return nil + } + out := new(PulsarGeoReplicationList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PulsarGeoReplicationList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarGeoReplicationSpec) DeepCopyInto(out *PulsarGeoReplicationSpec) { + *out = *in + out.ConnectionRef = in.ConnectionRef + out.DestinationConnectionRef = in.DestinationConnectionRef +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarGeoReplicationSpec. +func (in *PulsarGeoReplicationSpec) DeepCopy() *PulsarGeoReplicationSpec { + if in == nil { + return nil + } + out := new(PulsarGeoReplicationSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarGeoReplicationStatus) DeepCopyInto(out *PulsarGeoReplicationStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarGeoReplicationStatus. +func (in *PulsarGeoReplicationStatus) DeepCopy() *PulsarGeoReplicationStatus { + if in == nil { + return nil + } + out := new(PulsarGeoReplicationStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarNamespace) DeepCopyInto(out *PulsarNamespace) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarNamespace. +func (in *PulsarNamespace) DeepCopy() *PulsarNamespace { + if in == nil { + return nil + } + out := new(PulsarNamespace) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PulsarNamespace) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarNamespaceList) DeepCopyInto(out *PulsarNamespaceList) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ListMeta.DeepCopyInto(&out.ListMeta) + if in.Items != nil { + in, out := &in.Items, &out.Items + *out = make([]PulsarNamespace, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarNamespaceList. +func (in *PulsarNamespaceList) DeepCopy() *PulsarNamespaceList { + if in == nil { + return nil + } + out := new(PulsarNamespaceList) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PulsarNamespaceList) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarNamespaceSpec) DeepCopyInto(out *PulsarNamespaceSpec) { + *out = *in + if in.Bundles != nil { + in, out := &in.Bundles, &out.Bundles + *out = new(int32) + **out = **in + } + out.ConnectionRef = in.ConnectionRef + if in.MaxProducersPerTopic != nil { + in, out := &in.MaxProducersPerTopic, &out.MaxProducersPerTopic + *out = new(int32) + **out = **in + } + if in.MaxConsumersPerTopic != nil { + in, out := &in.MaxConsumersPerTopic, &out.MaxConsumersPerTopic + *out = new(int32) + **out = **in + } + if in.MaxConsumersPerSubscription != nil { + in, out := &in.MaxConsumersPerSubscription, &out.MaxConsumersPerSubscription + *out = new(int32) + **out = **in + } + if in.MessageTTL != nil { + in, out := &in.MessageTTL, &out.MessageTTL + *out = new(utils.Duration) + **out = **in + } + if in.RetentionTime != nil { + in, out := &in.RetentionTime, &out.RetentionTime + *out = new(utils.Duration) + **out = **in + } + if in.RetentionSize != nil { + in, out := &in.RetentionSize, &out.RetentionSize + x := (*in).DeepCopy() + *out = &x + } + if in.BacklogQuotaLimitTime != nil { + in, out := &in.BacklogQuotaLimitTime, &out.BacklogQuotaLimitTime + *out = new(utils.Duration) + **out = **in + } + if in.BacklogQuotaLimitSize != nil { + in, out := &in.BacklogQuotaLimitSize, &out.BacklogQuotaLimitSize + x := (*in).DeepCopy() + *out = &x + } + if in.BacklogQuotaRetentionPolicy != nil { + in, out := &in.BacklogQuotaRetentionPolicy, &out.BacklogQuotaRetentionPolicy + *out = new(string) + **out = **in + } + if in.BacklogQuotaType != nil { + in, out := &in.BacklogQuotaType, &out.BacklogQuotaType + *out = new(string) + **out = **in + } + if in.GeoReplicationRefs != nil { + in, out := &in.GeoReplicationRefs, &out.GeoReplicationRefs + *out = make([]*corev1.LocalObjectReference, len(*in)) + for i := range *in { + if (*in)[i] != nil { + in, out := &(*in)[i], &(*out)[i] + *out = new(corev1.LocalObjectReference) + **out = **in + } + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarNamespaceSpec. +func (in *PulsarNamespaceSpec) DeepCopy() *PulsarNamespaceSpec { + if in == nil { + return nil + } + out := new(PulsarNamespaceSpec) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarNamespaceStatus) DeepCopyInto(out *PulsarNamespaceStatus) { + *out = *in + if in.Conditions != nil { + in, out := &in.Conditions, &out.Conditions + *out = make([]v1.Condition, len(*in)) + for i := range *in { + (*in)[i].DeepCopyInto(&(*out)[i]) + } + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarNamespaceStatus. +func (in *PulsarNamespaceStatus) DeepCopy() *PulsarNamespaceStatus { + if in == nil { + return nil + } + out := new(PulsarNamespaceStatus) + in.DeepCopyInto(out) + return out +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarPackage) DeepCopyInto(out *PulsarPackage) { + *out = *in + out.TypeMeta = in.TypeMeta + in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) + in.Spec.DeepCopyInto(&out.Spec) + in.Status.DeepCopyInto(&out.Status) +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarPackage. +func (in *PulsarPackage) DeepCopy() *PulsarPackage { + if in == nil { + return nil + } + out := new(PulsarPackage) + in.DeepCopyInto(out) + return out +} + +// DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. +func (in *PulsarPackage) DeepCopyObject() runtime.Object { + if c := in.DeepCopy(); c != nil { + return c + } + return nil +} + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *PulsarPackageList) DeepCopyInto(out *PulsarPackageList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]PulsarConnection, len(*in)) + *out = make([]PulsarPackage, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarConnectionList. -func (in *PulsarConnectionList) DeepCopy() *PulsarConnectionList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarPackageList. +func (in *PulsarPackageList) DeepCopy() *PulsarPackageList { if in == nil { return nil } - out := new(PulsarConnectionList) + out := new(PulsarPackageList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PulsarConnectionList) DeepCopyObject() runtime.Object { +func (in *PulsarPackageList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -143,27 +818,30 @@ func (in *PulsarConnectionList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarConnectionSpec) DeepCopyInto(out *PulsarConnectionSpec) { +func (in *PulsarPackageSpec) DeepCopyInto(out *PulsarPackageSpec) { *out = *in - if in.Authentication != nil { - in, out := &in.Authentication, &out.Authentication - *out = new(PulsarAuthentication) - (*in).DeepCopyInto(*out) + out.ConnectionRef = in.ConnectionRef + if in.Properties != nil { + in, out := &in.Properties, &out.Properties + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarConnectionSpec. -func (in *PulsarConnectionSpec) DeepCopy() *PulsarConnectionSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarPackageSpec. +func (in *PulsarPackageSpec) DeepCopy() *PulsarPackageSpec { if in == nil { return nil } - out := new(PulsarConnectionSpec) + out := new(PulsarPackageSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarConnectionStatus) DeepCopyInto(out *PulsarConnectionStatus) { +func (in *PulsarPackageStatus) DeepCopyInto(out *PulsarPackageStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions @@ -174,37 +852,37 @@ func (in *PulsarConnectionStatus) DeepCopyInto(out *PulsarConnectionStatus) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarConnectionStatus. -func (in *PulsarConnectionStatus) DeepCopy() *PulsarConnectionStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarPackageStatus. +func (in *PulsarPackageStatus) DeepCopy() *PulsarPackageStatus { if in == nil { return nil } - out := new(PulsarConnectionStatus) + out := new(PulsarPackageStatus) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarGeoReplication) DeepCopyInto(out *PulsarGeoReplication) { +func (in *PulsarPermission) DeepCopyInto(out *PulsarPermission) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) - out.Spec = in.Spec + in.Spec.DeepCopyInto(&out.Spec) in.Status.DeepCopyInto(&out.Status) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarGeoReplication. -func (in *PulsarGeoReplication) DeepCopy() *PulsarGeoReplication { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarPermission. +func (in *PulsarPermission) DeepCopy() *PulsarPermission { if in == nil { return nil } - out := new(PulsarGeoReplication) + out := new(PulsarPermission) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PulsarGeoReplication) DeepCopyObject() runtime.Object { +func (in *PulsarPermission) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -212,31 +890,31 @@ func (in *PulsarGeoReplication) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarGeoReplicationList) DeepCopyInto(out *PulsarGeoReplicationList) { +func (in *PulsarPermissionList) DeepCopyInto(out *PulsarPermissionList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]PulsarGeoReplication, len(*in)) + *out = make([]PulsarPermission, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarGeoReplicationList. -func (in *PulsarGeoReplicationList) DeepCopy() *PulsarGeoReplicationList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarPermissionList. +func (in *PulsarPermissionList) DeepCopy() *PulsarPermissionList { if in == nil { return nil } - out := new(PulsarGeoReplicationList) + out := new(PulsarPermissionList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PulsarGeoReplicationList) DeepCopyObject() runtime.Object { +func (in *PulsarPermissionList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -244,24 +922,33 @@ func (in *PulsarGeoReplicationList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarGeoReplicationSpec) DeepCopyInto(out *PulsarGeoReplicationSpec) { +func (in *PulsarPermissionSpec) DeepCopyInto(out *PulsarPermissionSpec) { *out = *in out.ConnectionRef = in.ConnectionRef - out.DestinationConnectionRef = in.DestinationConnectionRef + if in.Roles != nil { + in, out := &in.Roles, &out.Roles + *out = make([]string, len(*in)) + copy(*out, *in) + } + if in.Actions != nil { + in, out := &in.Actions, &out.Actions + *out = make([]string, len(*in)) + copy(*out, *in) + } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarGeoReplicationSpec. -func (in *PulsarGeoReplicationSpec) DeepCopy() *PulsarGeoReplicationSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarPermissionSpec. +func (in *PulsarPermissionSpec) DeepCopy() *PulsarPermissionSpec { if in == nil { return nil } - out := new(PulsarGeoReplicationSpec) + out := new(PulsarPermissionSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarGeoReplicationStatus) DeepCopyInto(out *PulsarGeoReplicationStatus) { +func (in *PulsarPermissionStatus) DeepCopyInto(out *PulsarPermissionStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions @@ -272,18 +959,18 @@ func (in *PulsarGeoReplicationStatus) DeepCopyInto(out *PulsarGeoReplicationStat } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarGeoReplicationStatus. -func (in *PulsarGeoReplicationStatus) DeepCopy() *PulsarGeoReplicationStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarPermissionStatus. +func (in *PulsarPermissionStatus) DeepCopy() *PulsarPermissionStatus { if in == nil { return nil } - out := new(PulsarGeoReplicationStatus) + out := new(PulsarPermissionStatus) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarNamespace) DeepCopyInto(out *PulsarNamespace) { +func (in *PulsarSink) DeepCopyInto(out *PulsarSink) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) @@ -291,18 +978,18 @@ func (in *PulsarNamespace) DeepCopyInto(out *PulsarNamespace) { in.Status.DeepCopyInto(&out.Status) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarNamespace. -func (in *PulsarNamespace) DeepCopy() *PulsarNamespace { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarSink. +func (in *PulsarSink) DeepCopy() *PulsarSink { if in == nil { return nil } - out := new(PulsarNamespace) + out := new(PulsarSink) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PulsarNamespace) DeepCopyObject() runtime.Object { +func (in *PulsarSink) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -310,31 +997,31 @@ func (in *PulsarNamespace) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarNamespaceList) DeepCopyInto(out *PulsarNamespaceList) { +func (in *PulsarSinkList) DeepCopyInto(out *PulsarSinkList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]PulsarNamespace, len(*in)) + *out = make([]PulsarSink, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarNamespaceList. -func (in *PulsarNamespaceList) DeepCopy() *PulsarNamespaceList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarSinkList. +func (in *PulsarSinkList) DeepCopy() *PulsarSinkList { if in == nil { return nil } - out := new(PulsarNamespaceList) + out := new(PulsarSinkList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PulsarNamespaceList) DeepCopyObject() runtime.Object { +func (in *PulsarSinkList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -342,89 +1029,93 @@ func (in *PulsarNamespaceList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarNamespaceSpec) DeepCopyInto(out *PulsarNamespaceSpec) { +func (in *PulsarSinkSpec) DeepCopyInto(out *PulsarSinkSpec) { *out = *in - if in.Bundles != nil { - in, out := &in.Bundles, &out.Bundles - *out = new(int32) + if in.TopicsPattern != nil { + in, out := &in.TopicsPattern, &out.TopicsPattern + *out = new(string) **out = **in } - out.ConnectionRef = in.ConnectionRef - if in.MaxProducersPerTopic != nil { - in, out := &in.MaxProducersPerTopic, &out.MaxProducersPerTopic - *out = new(int32) + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(Resources) **out = **in } - if in.MaxConsumersPerTopic != nil { - in, out := &in.MaxConsumersPerTopic, &out.MaxConsumersPerTopic - *out = new(int32) + if in.TimeoutMs != nil { + in, out := &in.TimeoutMs, &out.TimeoutMs + *out = new(int64) **out = **in } - if in.MaxConsumersPerSubscription != nil { - in, out := &in.MaxConsumersPerSubscription, &out.MaxConsumersPerSubscription - *out = new(int32) + if in.Archive != nil { + in, out := &in.Archive, &out.Archive + *out = new(PackageContentRef) **out = **in } - if in.MessageTTL != nil { - in, out := &in.MessageTTL, &out.MessageTTL - *out = new(utils.Duration) - **out = **in + if in.Inputs != nil { + in, out := &in.Inputs, &out.Inputs + *out = make([]string, len(*in)) + copy(*out, *in) } - if in.RetentionTime != nil { - in, out := &in.RetentionTime, &out.RetentionTime - *out = new(utils.Duration) - **out = **in + if in.TopicToSerdeClassName != nil { + in, out := &in.TopicToSerdeClassName, &out.TopicToSerdeClassName + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } } - if in.RetentionSize != nil { - in, out := &in.RetentionSize, &out.RetentionSize - x := (*in).DeepCopy() - *out = &x + if in.TopicToSchemaType != nil { + in, out := &in.TopicToSchemaType, &out.TopicToSchemaType + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } } - if in.BacklogQuotaLimitTime != nil { - in, out := &in.BacklogQuotaLimitTime, &out.BacklogQuotaLimitTime - *out = new(utils.Duration) - **out = **in + if in.InputSpecs != nil { + in, out := &in.InputSpecs, &out.InputSpecs + *out = make(map[string]ConsumerConfig, len(*in)) + for key, val := range *in { + (*out)[key] = *val.DeepCopy() + } } - if in.BacklogQuotaLimitSize != nil { - in, out := &in.BacklogQuotaLimitSize, &out.BacklogQuotaLimitSize - x := (*in).DeepCopy() - *out = &x + if in.Configs != nil { + in, out := &in.Configs, &out.Configs + *out = new(apiextensionsv1.JSON) + (*in).DeepCopyInto(*out) } - if in.BacklogQuotaRetentionPolicy != nil { - in, out := &in.BacklogQuotaRetentionPolicy, &out.BacklogQuotaRetentionPolicy - *out = new(string) - **out = **in + if in.TopicToSchemaProperties != nil { + in, out := &in.TopicToSchemaProperties, &out.TopicToSchemaProperties + *out = make(map[string]string, len(*in)) + for key, val := range *in { + (*out)[key] = val + } } - if in.BacklogQuotaType != nil { - in, out := &in.BacklogQuotaType, &out.BacklogQuotaType - *out = new(string) - **out = **in + if in.CustomRuntimeOptions != nil { + in, out := &in.CustomRuntimeOptions, &out.CustomRuntimeOptions + *out = new(apiextensionsv1.JSON) + (*in).DeepCopyInto(*out) } - if in.GeoReplicationRefs != nil { - in, out := &in.GeoReplicationRefs, &out.GeoReplicationRefs - *out = make([]*corev1.LocalObjectReference, len(*in)) - for i := range *in { - if (*in)[i] != nil { - in, out := &(*in)[i], &(*out)[i] - *out = new(corev1.LocalObjectReference) - **out = **in - } + if in.Secrets != nil { + in, out := &in.Secrets, &out.Secrets + *out = make(map[string]SecretKeyRef, len(*in)) + for key, val := range *in { + (*out)[key] = val } } + out.ConnectionRef = in.ConnectionRef } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarNamespaceSpec. -func (in *PulsarNamespaceSpec) DeepCopy() *PulsarNamespaceSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarSinkSpec. +func (in *PulsarSinkSpec) DeepCopy() *PulsarSinkSpec { if in == nil { return nil } - out := new(PulsarNamespaceSpec) + out := new(PulsarSinkSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarNamespaceStatus) DeepCopyInto(out *PulsarNamespaceStatus) { +func (in *PulsarSinkStatus) DeepCopyInto(out *PulsarSinkStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions @@ -435,18 +1126,18 @@ func (in *PulsarNamespaceStatus) DeepCopyInto(out *PulsarNamespaceStatus) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarNamespaceStatus. -func (in *PulsarNamespaceStatus) DeepCopy() *PulsarNamespaceStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarSinkStatus. +func (in *PulsarSinkStatus) DeepCopy() *PulsarSinkStatus { if in == nil { return nil } - out := new(PulsarNamespaceStatus) + out := new(PulsarSinkStatus) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarPermission) DeepCopyInto(out *PulsarPermission) { +func (in *PulsarSource) DeepCopyInto(out *PulsarSource) { *out = *in out.TypeMeta = in.TypeMeta in.ObjectMeta.DeepCopyInto(&out.ObjectMeta) @@ -454,18 +1145,18 @@ func (in *PulsarPermission) DeepCopyInto(out *PulsarPermission) { in.Status.DeepCopyInto(&out.Status) } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarPermission. -func (in *PulsarPermission) DeepCopy() *PulsarPermission { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarSource. +func (in *PulsarSource) DeepCopy() *PulsarSource { if in == nil { return nil } - out := new(PulsarPermission) + out := new(PulsarSource) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PulsarPermission) DeepCopyObject() runtime.Object { +func (in *PulsarSource) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -473,31 +1164,31 @@ func (in *PulsarPermission) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarPermissionList) DeepCopyInto(out *PulsarPermissionList) { +func (in *PulsarSourceList) DeepCopyInto(out *PulsarSourceList) { *out = *in out.TypeMeta = in.TypeMeta in.ListMeta.DeepCopyInto(&out.ListMeta) if in.Items != nil { in, out := &in.Items, &out.Items - *out = make([]PulsarPermission, len(*in)) + *out = make([]PulsarSource, len(*in)) for i := range *in { (*in)[i].DeepCopyInto(&(*out)[i]) } } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarPermissionList. -func (in *PulsarPermissionList) DeepCopy() *PulsarPermissionList { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarSourceList. +func (in *PulsarSourceList) DeepCopy() *PulsarSourceList { if in == nil { return nil } - out := new(PulsarPermissionList) + out := new(PulsarSourceList) in.DeepCopyInto(out) return out } // DeepCopyObject is an autogenerated deepcopy function, copying the receiver, creating a new runtime.Object. -func (in *PulsarPermissionList) DeepCopyObject() runtime.Object { +func (in *PulsarSourceList) DeepCopyObject() runtime.Object { if c := in.DeepCopy(); c != nil { return c } @@ -505,33 +1196,60 @@ func (in *PulsarPermissionList) DeepCopyObject() runtime.Object { } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarPermissionSpec) DeepCopyInto(out *PulsarPermissionSpec) { +func (in *PulsarSourceSpec) DeepCopyInto(out *PulsarSourceSpec) { *out = *in - out.ConnectionRef = in.ConnectionRef - if in.Roles != nil { - in, out := &in.Roles, &out.Roles - *out = make([]string, len(*in)) - copy(*out, *in) + if in.ProducerConfig != nil { + in, out := &in.ProducerConfig, &out.ProducerConfig + *out = new(ProducerConfig) + (*in).DeepCopyInto(*out) } - if in.Actions != nil { - in, out := &in.Actions, &out.Actions - *out = make([]string, len(*in)) - copy(*out, *in) + if in.Configs != nil { + in, out := &in.Configs, &out.Configs + *out = new(apiextensionsv1.JSON) + (*in).DeepCopyInto(*out) + } + if in.Secrets != nil { + in, out := &in.Secrets, &out.Secrets + *out = make(map[string]SecretKeyRef, len(*in)) + for key, val := range *in { + (*out)[key] = val + } + } + if in.Resources != nil { + in, out := &in.Resources, &out.Resources + *out = new(Resources) + **out = **in + } + if in.Archive != nil { + in, out := &in.Archive, &out.Archive + *out = new(PackageContentRef) + **out = **in + } + if in.CustomRuntimeOptions != nil { + in, out := &in.CustomRuntimeOptions, &out.CustomRuntimeOptions + *out = new(apiextensionsv1.JSON) + (*in).DeepCopyInto(*out) } + if in.BatchSourceConfig != nil { + in, out := &in.BatchSourceConfig, &out.BatchSourceConfig + *out = new(BatchSourceConfig) + (*in).DeepCopyInto(*out) + } + out.ConnectionRef = in.ConnectionRef } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarPermissionSpec. -func (in *PulsarPermissionSpec) DeepCopy() *PulsarPermissionSpec { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarSourceSpec. +func (in *PulsarSourceSpec) DeepCopy() *PulsarSourceSpec { if in == nil { return nil } - out := new(PulsarPermissionSpec) + out := new(PulsarSourceSpec) in.DeepCopyInto(out) return out } // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. -func (in *PulsarPermissionStatus) DeepCopyInto(out *PulsarPermissionStatus) { +func (in *PulsarSourceStatus) DeepCopyInto(out *PulsarSourceStatus) { *out = *in if in.Conditions != nil { in, out := &in.Conditions, &out.Conditions @@ -542,12 +1260,12 @@ func (in *PulsarPermissionStatus) DeepCopyInto(out *PulsarPermissionStatus) { } } -// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarPermissionStatus. -func (in *PulsarPermissionStatus) DeepCopy() *PulsarPermissionStatus { +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new PulsarSourceStatus. +func (in *PulsarSourceStatus) DeepCopy() *PulsarSourceStatus { if in == nil { return nil } - out := new(PulsarPermissionStatus) + out := new(PulsarSourceStatus) in.DeepCopyInto(out) return out } @@ -843,6 +1561,21 @@ func (in *PulsarTopicStatus) DeepCopy() *PulsarTopicStatus { return out } +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *Resources) DeepCopyInto(out *Resources) { + *out = *in +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new Resources. +func (in *Resources) DeepCopy() *Resources { + if in == nil { + return nil + } + out := new(Resources) + in.DeepCopyInto(out) + return out +} + // DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. func (in *SchemaInfo) DeepCopyInto(out *SchemaInfo) { *out = *in @@ -904,3 +1637,68 @@ func (in *ValueOrSecretRef) DeepCopy() *ValueOrSecretRef { in.DeepCopyInto(out) return out } + +// DeepCopyInto is an autogenerated deepcopy function, copying the receiver, writing into out. in must be non-nil. +func (in *WindowConfig) DeepCopyInto(out *WindowConfig) { + *out = *in + if in.WindowLengthCount != nil { + in, out := &in.WindowLengthCount, &out.WindowLengthCount + *out = new(int) + **out = **in + } + if in.WindowLengthDurationMs != nil { + in, out := &in.WindowLengthDurationMs, &out.WindowLengthDurationMs + *out = new(int64) + **out = **in + } + if in.SlidingIntervalCount != nil { + in, out := &in.SlidingIntervalCount, &out.SlidingIntervalCount + *out = new(int) + **out = **in + } + if in.SlidingIntervalDurationMs != nil { + in, out := &in.SlidingIntervalDurationMs, &out.SlidingIntervalDurationMs + *out = new(int64) + **out = **in + } + if in.LateDataTopic != nil { + in, out := &in.LateDataTopic, &out.LateDataTopic + *out = new(string) + **out = **in + } + if in.MaxLagMs != nil { + in, out := &in.MaxLagMs, &out.MaxLagMs + *out = new(int64) + **out = **in + } + if in.WatermarkEmitIntervalMs != nil { + in, out := &in.WatermarkEmitIntervalMs, &out.WatermarkEmitIntervalMs + *out = new(int64) + **out = **in + } + if in.TimestampExtractorClassName != nil { + in, out := &in.TimestampExtractorClassName, &out.TimestampExtractorClassName + *out = new(string) + **out = **in + } + if in.ActualWindowFunctionClassName != nil { + in, out := &in.ActualWindowFunctionClassName, &out.ActualWindowFunctionClassName + *out = new(string) + **out = **in + } + if in.ProcessingGuarantees != nil { + in, out := &in.ProcessingGuarantees, &out.ProcessingGuarantees + *out = new(string) + **out = **in + } +} + +// DeepCopy is an autogenerated deepcopy function, copying the receiver, creating a new WindowConfig. +func (in *WindowConfig) DeepCopy() *WindowConfig { + if in == nil { + return nil + } + out := new(WindowConfig) + in.DeepCopyInto(out) + return out +} diff --git a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarconnections.yaml b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarconnections.yaml index 541e284c..b8ce0ad8 100644 --- a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarconnections.yaml +++ b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarconnections.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 StreamNative +# Copyright 2024 StreamNative # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: pulsarconnections.resource.streamnative.io spec: group: resource.streamnative.io @@ -65,14 +65,19 @@ spec: description: PulsarConnection is the Schema for the pulsarconnections API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -163,8 +168,9 @@ spec: pattern: ^pulsar?://.+$ type: string clusterName: - description: ClusterName indicates the local cluster name of the pulsar - cluster. It should set when enabling the Geo Replication + description: |- + ClusterName indicates the local cluster name of the pulsar cluster. It should + set when enabling the Geo Replication type: string type: object status: @@ -174,43 +180,49 @@ spec: description: Represents the observations of a connection's current state. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -224,11 +236,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -244,9 +257,9 @@ spec: - type x-kubernetes-list-type: map observedGeneration: - description: ObservedGeneration is the most recent generation observed - for this resource. It corresponds to the metadata generation, which - is updated on mutation by the API Server. + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. format: int64 type: integer secretKeyHash: @@ -258,9 +271,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarfunctions.yaml b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarfunctions.yaml new file mode 100644 index 00000000..1de5bcff --- /dev/null +++ b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarfunctions.yaml @@ -0,0 +1,504 @@ +# Copyright 2024 StreamNative +# +# 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. + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: pulsarfunctions.resource.streamnative.io +spec: + group: resource.streamnative.io + names: + categories: + - pulsar + - pulsarres + kind: PulsarFunction + listKind: PulsarFunctionList + plural: pulsarfunctions + shortNames: + - pfunction + singular: pulsarfunction + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.name + name: RESOURCE_NAME + type: string + - jsonPath: .metadata.generation + name: GENERATION + type: string + - jsonPath: .status.observedGeneration + name: OBSERVED_GENERATION + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: READY + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: PulsarFunction is the Schema for the pulsar functions API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: PulsarFunctionSpec defines the desired state of PulsarFunction + properties: + autoAck: + description: AutoAck is the flag to indicate whether the function + should auto ack + type: boolean + batchBuilder: + description: BatchBuilder is the batch builder that the function uses + type: string + className: + description: ClassName is the class name of the function + type: string + cleanupSubscription: + description: CleanupSubscription is the flag to indicate whether the + subscription should be cleaned up when the function is deleted + type: boolean + connectionRef: + description: ConnectionRef is the reference to the PulsarConnection + resource + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + customRuntimeOptions: + description: CustomRuntimeOptions is the custom runtime options of + the function + x-kubernetes-preserve-unknown-fields: true + customSchemaInputs: + additionalProperties: + type: string + description: CustomSchemaInputs is the custom schema inputs of the + function + type: object + customSchemaOutputs: + additionalProperties: + type: string + description: CustomSchemaOutputs is the custom schema outputs of the + function + type: object + customSerdeInputs: + additionalProperties: + type: string + description: CustomSerdeInputs is the custom serde inputs of the function + type: object + deadLetterTopic: + description: DeadLetterTopic is the dead letter topic of the function + type: string + exposePulsarAdminClientEnabled: + description: ExposePulsarAdminClientEnabled is the flag to indicate + whether the function should expose pulsar admin client + type: boolean + forwardSourceMessageProperty: + description: ForwardSourceMessageProperty is the flag to indicate + whether the function should forward source message properties + type: boolean + go: + description: Go is the go of the function + properties: + url: + type: string + type: object + inputSpecs: + additionalProperties: + description: ConsumerConfig represents the configuration for the + consumer of the pulsar functions and connectors + properties: + consumerProperties: + additionalProperties: + type: string + type: object + cryptoConfig: + description: CryptoConfig represents the configuration for the + crypto of the pulsar functions and connectors + properties: + consumerCryptoFailureAction: + type: string + cryptoKeyReaderClassName: + type: string + cryptoKeyReaderConfig: + additionalProperties: + type: string + type: object + encryptionKeys: + items: + type: string + type: array + producerCryptoFailureAction: + type: string + required: + - consumerCryptoFailureAction + - cryptoKeyReaderClassName + - cryptoKeyReaderConfig + - encryptionKeys + - producerCryptoFailureAction + type: object + poolMessages: + type: boolean + receiverQueueSize: + type: integer + regexPattern: + type: boolean + schemaProperties: + additionalProperties: + type: string + type: object + schemaType: + type: string + serdeClassName: + type: string + type: object + description: InputSpecs is the input specs of the function + type: object + inputTypeClassName: + description: InputTypeClassName is the input type class name of the + function + type: string + inputs: + description: Inputs is the inputs of the function + items: + type: string + type: array + jar: + description: Jar is the jar of the function + properties: + url: + type: string + type: object + lifecyclePolicy: + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion + enum: + - CleanUpAfterDeletion + - KeepAfterDeletion + type: string + logTopic: + description: LogTopic is the log topic of the function + type: string + maxMessageRetries: + description: MaxMessageRetries is the max message retries of the function + type: integer + maxPendingAsyncRequests: + description: MaxPendingAsyncRequests is the max pending async requests + of the function + type: integer + name: + description: Name is the name of the function + type: string + namespace: + description: Namespace is the namespace of the function + type: string + output: + description: Output is the output of the function + type: string + outputSchemaType: + description: OutputSchemaType is the output schema type of the function + type: string + outputSerdeClassName: + description: OutputSerdeClassName is the output serde class name of + the function + type: string + outputTypeClassName: + description: OutputTypeClassName is the output type class name of + the function + type: string + parallelism: + description: Parallelism is the parallelism of the function + type: integer + processingGuarantees: + description: ProcessingGuarantees is the processing guarantees of + the function + type: string + producerConfig: + description: ProducerConfig is the producer config of the function + properties: + batchBuilder: + type: string + compressionType: + type: string + cryptoConfig: + description: CryptoConfig represents the configuration for the + crypto of the pulsar functions and connectors + properties: + consumerCryptoFailureAction: + type: string + cryptoKeyReaderClassName: + type: string + cryptoKeyReaderConfig: + additionalProperties: + type: string + type: object + encryptionKeys: + items: + type: string + type: array + producerCryptoFailureAction: + type: string + required: + - consumerCryptoFailureAction + - cryptoKeyReaderClassName + - cryptoKeyReaderConfig + - encryptionKeys + - producerCryptoFailureAction + type: object + maxPendingMessages: + type: integer + maxPendingMessagesAcrossPartitions: + type: integer + useThreadLocalProducers: + type: boolean + required: + - batchBuilder + - compressionType + - cryptoConfig + - maxPendingMessages + - maxPendingMessagesAcrossPartitions + - useThreadLocalProducers + type: object + py: + description: Py is the py of the function + properties: + url: + type: string + type: object + resources: + description: Resources is the resources of the function + properties: + cpu: + type: string + disk: + format: int64 + type: integer + ram: + format: int64 + type: integer + required: + - cpu + - disk + - ram + type: object + retainKeyOrdering: + description: RetainKeyOrdering is the flag to indicate whether the + function should retain key ordering + type: boolean + retainOrdering: + description: RetainOrdering is the flag to indicate whether the function + should retain ordering + type: boolean + runtimeFlags: + description: RuntimeFlags is the runtime flags of the function + type: string + secrets: + additionalProperties: + description: SecretKeyRef indicates a secret name and key + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + description: Secrets is the secrets of the function + type: object + skipToLatest: + description: SkipToLatest is the flag to indicate whether the function + should skip to latest + type: boolean + subName: + description: SubName is the sub name of the function + type: string + subscriptionPosition: + description: SubscriptionPosition is the subscription position of + the function + type: string + tenant: + description: Tenant is the tenant of the function + type: string + timeoutMs: + description: TimeoutMs is the function timeout in milliseconds + format: int64 + type: integer + topicsPattern: + description: TopicsPattern is the topics pattern that the function + subscribes to + type: string + userConfig: + description: UserConfig is the user config of the function + x-kubernetes-preserve-unknown-fields: true + windowConfig: + description: WindowConfig is the window config of the function + properties: + actualWindowFunctionClassName: + type: string + lateDataTopic: + type: string + maxLagMs: + format: int64 + type: integer + processingGuarantees: + type: string + slidingIntervalCount: + type: integer + slidingIntervalDurationMs: + format: int64 + type: integer + timestampExtractorClassName: + type: string + watermarkEmitIntervalMs: + format: int64 + type: integer + windowLengthCount: + type: integer + windowLengthDurationMs: + format: int64 + type: integer + required: + - actualWindowFunctionClassName + - lateDataTopic + - maxLagMs + - processingGuarantees + - slidingIntervalCount + - slidingIntervalDurationMs + - timestampExtractorClassName + - watermarkEmitIntervalMs + - windowLengthCount + - windowLengthDurationMs + type: object + required: + - connectionRef + type: object + status: + description: PulsarFunctionStatus defines the observed state of PulsarFunction + properties: + conditions: + description: Represents the observations of a connection's current + state. + items: + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsargeoreplications.yaml b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsargeoreplications.yaml index 80fcc76a..03c7d2d6 100644 --- a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsargeoreplications.yaml +++ b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsargeoreplications.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 StreamNative +# Copyright 2024 StreamNative # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: pulsargeoreplications.resource.streamnative.io spec: group: resource.streamnative.io @@ -35,14 +35,19 @@ spec: API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -53,23 +58,30 @@ spec: description: ConnectionRef is the reference to the source PulsarConnection properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic destinationConnectionRef: description: DestinationConnectionRef is the connection reference to the remote cluster properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic lifecyclePolicy: - description: PulsarResourceLifeCyclePolicy indicates whether it will - keep or delete the resource in pulsar cluster after resource is - deleted by controller KeepAfterDeletion or CleanUpAfterDeletion + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion enum: - CleanUpAfterDeletion - KeepAfterDeletion @@ -86,43 +98,49 @@ spec: description: Conditions Represents the observations of a connection's current state. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -136,11 +154,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -156,9 +175,9 @@ spec: - type x-kubernetes-list-type: map observedGeneration: - description: ObservedGeneration is the most recent generation observed - for this resource. It corresponds to the metadata generation, which - is updated on mutation by the API Server. + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. format: int64 type: integer type: object @@ -167,9 +186,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarnamespaces.yaml b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarnamespaces.yaml index e542a3b0..c9855b7f 100644 --- a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarnamespaces.yaml +++ b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarnamespaces.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 StreamNative +# Copyright 2024 StreamNative # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: pulsarnamespaces.resource.streamnative.io spec: group: resource.streamnative.io @@ -52,14 +52,19 @@ spec: description: PulsarNamespace is the Schema for the pulsarnamespaces API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -73,14 +78,16 @@ spec: pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true backlogQuotaLimitTime: - description: Backlog Should set at least one of them if setting backlog + description: |- + Backlog + Should set at least one of them if setting backlog type: string backlogQuotaRetentionPolicy: type: string backlogQuotaType: - description: BacklogQuotaType controls the backlog by setting the - type to destination_storage or message_age destination_storage limits - backlog by size (in bytes). message_age limits backlog by time, + description: |- + BacklogQuotaType controls the backlog by setting the type to destination_storage or message_age + destination_storage limits backlog by size (in bytes). message_age limits backlog by time, that is, message timestamp (broker or publish timestamp) enum: - destination_storage @@ -94,27 +101,35 @@ spec: resource properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic geoReplicationRefs: description: GeoReplicationRefs is the reference list to the PulsarGeoReplication resource items: - description: LocalObjectReference contains enough information to - let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic type: array lifecyclePolicy: - description: PulsarResourceLifeCyclePolicy indicates whether it will - keep or delete the resource in pulsar cluster after resource is - deleted by controller KeepAfterDeletion or CleanUpAfterDeletion + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion enum: - CleanUpAfterDeletion - KeepAfterDeletion @@ -142,9 +157,10 @@ spec: pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true retentionTime: - description: Retention Should set at least one of them if setting - retention Retention Quota must exceed configured backlog quota for - namespace + description: |- + Retention + Should set at least one of them if setting retention + Retention Quota must exceed configured backlog quota for namespace type: string required: - connectionRef @@ -157,43 +173,49 @@ spec: description: Represents the observations of a connection's current state. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -207,11 +229,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -230,9 +253,9 @@ spec: description: GeoReplicationEnabled type: boolean observedGeneration: - description: ObservedGeneration is the most recent generation observed - for this resource. It corresponds to the metadata generation, which - is updated on mutation by the API Server. + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. format: int64 type: integer type: object @@ -241,9 +264,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarpackages.yaml b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarpackages.yaml new file mode 100644 index 00000000..eb3b62b8 --- /dev/null +++ b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarpackages.yaml @@ -0,0 +1,210 @@ +# Copyright 2024 StreamNative +# +# 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. + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: pulsarpackages.resource.streamnative.io +spec: + group: resource.streamnative.io + names: + categories: + - pulsar + - pulsarres + kind: PulsarPackage + listKind: PulsarPackageList + plural: pulsarpackages + shortNames: + - ppackage + singular: pulsarpackage + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.name + name: RESOURCE_NAME + type: string + - jsonPath: .metadata.generation + name: GENERATION + type: string + - jsonPath: .status.observedGeneration + name: OBSERVED_GENERATION + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: READY + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: PulsarPackage is the Schema for the pulsar package management + service's package API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: PulsarPackageSpec defines the desired state of PulsarPackage + properties: + connectionRef: + description: ConnectionRef is the reference to the PulsarConnection + resource + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + contact: + type: string + description: + type: string + fileURL: + description: FileURL is the download-able URL of the package from + http or https protocol + type: string + lifecyclePolicy: + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion + enum: + - CleanUpAfterDeletion + - KeepAfterDeletion + type: string + packageURL: + description: PackageURL is the Pulsar Package URL, in format of type://tenant/namespace/package@version + type: string + properties: + additionalProperties: + type: string + type: object + required: + - connectionRef + - fileURL + - packageURL + type: object + status: + description: PulsarPackageStatus defines the observed state of PulsarPackage + properties: + conditions: + description: Represents the observations of a connection's current + state. + items: + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarpermissions.yaml b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarpermissions.yaml index 532a729b..2ab07071 100644 --- a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarpermissions.yaml +++ b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarpermissions.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 StreamNative +# Copyright 2024 StreamNative # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: pulsarpermissions.resource.streamnative.io spec: group: resource.streamnative.io @@ -61,14 +61,19 @@ spec: description: PulsarPermission is the Schema for the pulsarpermissions API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -76,8 +81,9 @@ spec: description: PulsarPermissionSpec defines the desired state of PulsarPermission properties: actions: - description: Actions contains a list of action to grant. the options - include produce,consume,functions + description: |- + Actions contains a list of action to grant. + the options include produce,consume,functions items: type: string type: array @@ -86,13 +92,17 @@ spec: resource properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic lifecyclePolicy: - description: LifecyclePolicy is the policy that how to deal with pulsar - resource when PulsarPermission is deleted + description: |- + LifecyclePolicy is the policy that how to deal with pulsar resource when + PulsarPermission is deleted type: string resourceName: description: ResourceName name of the target resource which will be @@ -106,8 +116,9 @@ spec: - topic type: string roles: - description: Roles contains a list of role which will be granted the - same permissions for the same target + description: |- + Roles contains a list of role which will be granted the same permissions + for the same target items: type: string type: array @@ -124,43 +135,49 @@ spec: description: Represents the observations of a connection's current state. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -174,11 +191,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -194,9 +212,9 @@ spec: - type x-kubernetes-list-type: map observedGeneration: - description: ObservedGeneration is the most recent generation observed - for this resource. It corresponds to the metadata generation, which - is updated on mutation by the API Server. + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. format: int64 type: integer type: object @@ -205,9 +223,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarsinks.yaml b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarsinks.yaml new file mode 100644 index 00000000..fc0fe8a2 --- /dev/null +++ b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarsinks.yaml @@ -0,0 +1,387 @@ +# Copyright 2024 StreamNative +# +# 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. + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: pulsarsinks.resource.streamnative.io +spec: + group: resource.streamnative.io + names: + categories: + - pulsar + - pulsarres + kind: PulsarSink + listKind: PulsarSinkList + plural: pulsarsinks + shortNames: + - psink + singular: pulsarsink + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.name + name: RESOURCE_NAME + type: string + - jsonPath: .metadata.generation + name: GENERATION + type: string + - jsonPath: .status.observedGeneration + name: OBSERVED_GENERATION + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: READY + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: PulsarSink is the Schema for the pulsar functions API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: PulsarSinkSpec defines the desired state of PulsarSink + properties: + archive: + description: Archive is the archive of the PulsarSink + properties: + url: + type: string + type: object + autoAck: + description: AutoAck is the flag to enable or disable the auto ack + type: boolean + className: + description: ClassName is the class name of the PulsarSink + type: string + cleanupSubscription: + description: CleanupSubscription is the flag to enable or disable + the cleanup of subscription + type: boolean + configs: + description: Configs is the map of configs of the PulsarSink + x-kubernetes-preserve-unknown-fields: true + connectionRef: + description: ConnectionRef is the reference to the PulsarConnection + resource + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + customRuntimeOptions: + description: CustomRuntimeOptions is the custom runtime options of + the PulsarSink + x-kubernetes-preserve-unknown-fields: true + deadLetterTopic: + description: DeadLetterTopic is the dead letter topic of the PulsarSink + type: string + inputSpecs: + additionalProperties: + description: ConsumerConfig represents the configuration for the + consumer of the pulsar functions and connectors + properties: + consumerProperties: + additionalProperties: + type: string + type: object + cryptoConfig: + description: CryptoConfig represents the configuration for the + crypto of the pulsar functions and connectors + properties: + consumerCryptoFailureAction: + type: string + cryptoKeyReaderClassName: + type: string + cryptoKeyReaderConfig: + additionalProperties: + type: string + type: object + encryptionKeys: + items: + type: string + type: array + producerCryptoFailureAction: + type: string + required: + - consumerCryptoFailureAction + - cryptoKeyReaderClassName + - cryptoKeyReaderConfig + - encryptionKeys + - producerCryptoFailureAction + type: object + poolMessages: + type: boolean + receiverQueueSize: + type: integer + regexPattern: + type: boolean + schemaProperties: + additionalProperties: + type: string + type: object + schemaType: + type: string + serdeClassName: + type: string + type: object + description: InputSpecs is the map of input specs of the PulsarSink + type: object + inputs: + description: Inputs is the list of inputs of the PulsarSink + items: + type: string + type: array + lifecyclePolicy: + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion + enum: + - CleanUpAfterDeletion + - KeepAfterDeletion + type: string + maxMessageRetries: + description: MaxMessageRetries is the max message retries of the PulsarSink + type: integer + name: + description: Name is the name of the PulsarSink + type: string + namespace: + description: Namespace is the namespace of the PulsarSink + type: string + negativeAckRedeliveryDelayMs: + description: NegativeAckRedeliveryDelayMs is the negative ack redelivery + delay in milliseconds of the PulsarSink + format: int64 + type: integer + parallelism: + description: Parallelism is the parallelism of the PulsarSink + type: integer + processingGuarantees: + description: ProcessingGuarantees is the processing guarantees of + the PulsarSink + type: string + resources: + description: Resources is the resource requirements for the PulsarSink + properties: + cpu: + type: string + disk: + format: int64 + type: integer + ram: + format: int64 + type: integer + required: + - cpu + - disk + - ram + type: object + retainKeyOrdering: + description: RetainKeyOrdering is the flag to enable or disable the + retain key ordering + type: boolean + retainOrdering: + description: RetainOrdering is the flag to enable or disable the retain + ordering + type: boolean + runtimeFlags: + description: RuntimeFlags is the runtime flags of the PulsarSink + type: string + secrets: + additionalProperties: + description: SecretKeyRef indicates a secret name and key + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + description: Secrets is the map of secrets of the PulsarSink + type: object + sinkType: + description: SinkType is the type of the PulsarSink + type: string + sourceSubscriptionName: + description: SourceSubscriptionName is the source subscription name + of the PulsarSink + type: string + sourceSubscriptionPosition: + description: SourceSubscriptionPosition is the source subscription + position of the PulsarSink + type: string + tenant: + description: Tenant is the tenant of the PulsarSink + type: string + timeoutMs: + description: TimeoutMs is the timeout in milliseconds for the PulsarSink + format: int64 + type: integer + topicToSchemaProperties: + additionalProperties: + type: string + description: TopicToSchemaProperties is the map of topic to schema + properties of the PulsarSink + type: object + topicToSchemaType: + additionalProperties: + type: string + description: TopicToSchemaType is the map of topic to schema type + of the PulsarSink + type: object + topicToSerdeClassName: + additionalProperties: + type: string + description: TopicToSerdeClassName is the map of topic to serde class + name of the PulsarSink + type: object + topicsPattern: + description: TopicsPattern is the pattern of topics to consume from + Pulsar + type: string + transformFunction: + description: TransformFunction is the transform function of the PulsarSink + type: string + transformFunctionClassName: + description: TransformFunctionClassName is the transform function + class name of the PulsarSink + type: string + transformFunctionConfig: + description: TransformFunctionConfig is the transform function config + of the PulsarSink + type: string + required: + - connectionRef + type: object + status: + description: PulsarSinkStatus defines the observed state of PulsarSink + properties: + conditions: + description: Represents the observations of a connection's current + state. + items: + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarsources.yaml b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarsources.yaml new file mode 100644 index 00000000..fa165869 --- /dev/null +++ b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsarsources.yaml @@ -0,0 +1,326 @@ +# Copyright 2024 StreamNative +# +# 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. + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: pulsarsources.resource.streamnative.io +spec: + group: resource.streamnative.io + names: + categories: + - pulsar + - pulsarres + kind: PulsarSource + listKind: PulsarSourceList + plural: pulsarsources + shortNames: + - psource + singular: pulsarsource + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.name + name: RESOURCE_NAME + type: string + - jsonPath: .metadata.generation + name: GENERATION + type: string + - jsonPath: .status.observedGeneration + name: OBSERVED_GENERATION + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: READY + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: PulsarSource is the Schema for the pulsar functions API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: PulsarSourceSpec defines the desired state of PulsarSource + properties: + archive: + description: Archive is the archive of the PulsarSource + properties: + url: + type: string + type: object + batchBuilder: + description: BatchBuilder is the batch builder of the PulsarSource + type: string + batchSourceConfig: + description: BatchSourceConfig is the batch source config of the PulsarSource + properties: + discoveryTriggererClassName: + type: string + discoveryTriggererConfig: + x-kubernetes-preserve-unknown-fields: true + required: + - discoveryTriggererClassName + - discoveryTriggererConfig + type: object + className: + description: ClassName is the class name of the + type: string + configs: + description: Configs is the map of configs of the PulsarSource + x-kubernetes-preserve-unknown-fields: true + connectionRef: + description: ConnectionRef is the reference to the PulsarConnection + resource + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + customRuntimeOptions: + description: CustomRuntimeOptions is the custom runtime options of + the PulsarSource + x-kubernetes-preserve-unknown-fields: true + lifecyclePolicy: + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion + enum: + - CleanUpAfterDeletion + - KeepAfterDeletion + type: string + name: + description: Name is the name of the PulsarSource + type: string + namespace: + description: Namespace is the namespace of the PulsarSource + type: string + parallelism: + description: Parallelism is the parallelism of the PulsarSource + type: integer + processingGuarantees: + description: ProcessingGuarantees is the processing guarantees of + the PulsarSource + type: string + producerConfig: + description: ProducerConfig is the producer config of the PulsarSource + properties: + batchBuilder: + type: string + compressionType: + type: string + cryptoConfig: + description: CryptoConfig represents the configuration for the + crypto of the pulsar functions and connectors + properties: + consumerCryptoFailureAction: + type: string + cryptoKeyReaderClassName: + type: string + cryptoKeyReaderConfig: + additionalProperties: + type: string + type: object + encryptionKeys: + items: + type: string + type: array + producerCryptoFailureAction: + type: string + required: + - consumerCryptoFailureAction + - cryptoKeyReaderClassName + - cryptoKeyReaderConfig + - encryptionKeys + - producerCryptoFailureAction + type: object + maxPendingMessages: + type: integer + maxPendingMessagesAcrossPartitions: + type: integer + useThreadLocalProducers: + type: boolean + required: + - batchBuilder + - compressionType + - cryptoConfig + - maxPendingMessages + - maxPendingMessagesAcrossPartitions + - useThreadLocalProducers + type: object + resources: + description: Resources is the resources of the PulsarSource + properties: + cpu: + type: string + disk: + format: int64 + type: integer + ram: + format: int64 + type: integer + required: + - cpu + - disk + - ram + type: object + runtimeFlags: + description: RuntimeFlags is the runtime flags of the PulsarSource + type: string + schemaType: + description: SchemaType is the schema type of the PulsarSource + type: string + secrets: + additionalProperties: + description: SecretKeyRef indicates a secret name and key + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + description: Secrets is the map of secrets of the PulsarSource + type: object + serdeClassName: + description: SerdeClassName is the serde class name of the PulsarSource + type: string + tenant: + description: Tenant is the tenant of the PulsarSource + type: string + topicName: + description: TopicName is the topic name of the PulsarSource + type: string + required: + - connectionRef + type: object + status: + description: PulsarSourceStatus defines the observed state of PulsarSource + properties: + conditions: + description: Represents the observations of a connection's current + state. + items: + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsartenants.yaml b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsartenants.yaml index a887dc11..d4d83ba4 100644 --- a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsartenants.yaml +++ b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsartenants.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 StreamNative +# Copyright 2024 StreamNative # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: pulsartenants.resource.streamnative.io spec: group: resource.streamnative.io @@ -52,14 +52,19 @@ spec: description: PulsarTenant is the Schema for the pulsartenants API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -79,27 +84,35 @@ spec: resource properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic geoReplicationRefs: description: GeoReplicationRefs is the reference list to the PulsarGeoReplication resource items: - description: LocalObjectReference contains enough information to - let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic type: array lifecyclePolicy: - description: PulsarResourceLifeCyclePolicy indicates whether it will - keep or delete the resource in pulsar cluster after resource is - deleted by controller KeepAfterDeletion or CleanUpAfterDeletion + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion enum: - CleanUpAfterDeletion - KeepAfterDeletion @@ -118,43 +131,49 @@ spec: description: Represents the observations of a connection's current state. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -168,11 +187,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -188,9 +208,9 @@ spec: - type x-kubernetes-list-type: map observedGeneration: - description: ObservedGeneration is the most recent generation observed - for this resource. It corresponds to the metadata generation, which - is updated on mutation by the API Server. + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. format: int64 type: integer type: object @@ -199,9 +219,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsartopics.yaml b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsartopics.yaml index 934bc9b9..09a384a1 100644 --- a/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsartopics.yaml +++ b/charts/pulsar-resources-operator/crds/resource.streamnative.io_pulsartopics.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 StreamNative +# Copyright 2024 StreamNative # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: pulsartopics.resource.streamnative.io spec: group: resource.streamnative.io @@ -52,14 +52,19 @@ spec: description: PulsarTopic is the Schema for the pulsartopics API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -73,7 +78,9 @@ spec: pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true backlogQuotaLimitTime: - description: Backlog Should set at least one of them if setting backlog + description: |- + Backlog + Should set at least one of them if setting backlog type: string backlogQuotaRetentionPolicy: type: string @@ -82,27 +89,35 @@ spec: resource properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic geoReplicationRefs: description: GeoReplicationRefs is the reference list to the PulsarGeoReplication resource items: - description: LocalObjectReference contains enough information to - let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic type: array lifecyclePolicy: - description: PulsarResourceLifeCyclePolicy indicates whether it will - keep or delete the resource in pulsar cluster after resource is - deleted by controller KeepAfterDeletion or CleanUpAfterDeletion + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion enum: - CleanUpAfterDeletion - KeepAfterDeletion @@ -141,14 +156,15 @@ spec: pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true retentionTime: - description: Retention Should set at least one of them if setting - retention Retention Quota must exceed configured backlog quota for - topic + description: |- + Retention + Should set at least one of them if setting retention + Retention Quota must exceed configured backlog quota for topic type: string schemaInfo: - description: SchemaInfo defines the Pulsar Schema. It is stored and - enforced on a per-topic basis and cannot be stored at the namespace - or tenant level. + description: |- + SchemaInfo defines the Pulsar Schema. + It is stored and enforced on a per-topic basis and cannot be stored at the namespace or tenant level. properties: properties: additionalProperties: @@ -174,43 +190,49 @@ spec: description: Represents the observations of a connection's current state. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -224,11 +246,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -247,9 +270,9 @@ spec: description: GeoReplicationEnabled type: boolean observedGeneration: - description: ObservedGeneration is the most recent generation observed - for this resource. It corresponds to the metadata generation, which - is updated on mutation by the API Server. + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. format: int64 type: integer type: object @@ -258,9 +281,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/charts/pulsar-resources-operator/templates/role.yaml b/charts/pulsar-resources-operator/templates/role.yaml index 2af3cc31..0ed44a43 100644 --- a/charts/pulsar-resources-operator/templates/role.yaml +++ b/charts/pulsar-resources-operator/templates/role.yaml @@ -23,7 +23,7 @@ rules: - apiGroups: - "" resources: - - configmaps + - secrets verbs: - create - delete @@ -33,9 +33,9 @@ rules: - update - watch - apiGroups: - - "" + - resource.streamnative.io resources: - - secrets + - pulsarconnections verbs: - create - delete @@ -47,7 +47,21 @@ rules: - apiGroups: - resource.streamnative.io resources: - - pulsarconnections + - pulsarconnections/finalizers + verbs: + - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsarconnections/status + verbs: + - get + - patch + - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsarfunctions verbs: - create - delete @@ -59,13 +73,39 @@ rules: - apiGroups: - resource.streamnative.io resources: - - pulsarconnections/finalizers + - pulsarfunctions/finalizers verbs: - update - apiGroups: - resource.streamnative.io resources: - - pulsarconnections/status + - pulsarfunctions/status + verbs: + - get + - patch + - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsargeoreplications + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsargeoreplications/finalizers + verbs: + - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsargeoreplications/status verbs: - get - patch @@ -96,6 +136,32 @@ rules: - get - patch - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsarpackages + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsarpackages/finalizers + verbs: + - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsarpackages/status + verbs: + - get + - patch + - update - apiGroups: - resource.streamnative.io resources: @@ -125,7 +191,7 @@ rules: - apiGroups: - resource.streamnative.io resources: - - pulsartenants + - pulsarsinks verbs: - create - delete @@ -137,13 +203,13 @@ rules: - apiGroups: - resource.streamnative.io resources: - - pulsartenants/finalizers + - pulsarsinks/finalizers verbs: - update - apiGroups: - resource.streamnative.io resources: - - pulsartenants/status + - pulsarsinks/status verbs: - get - patch @@ -151,7 +217,7 @@ rules: - apiGroups: - resource.streamnative.io resources: - - pulsartopics + - pulsarsources verbs: - create - delete @@ -163,13 +229,13 @@ rules: - apiGroups: - resource.streamnative.io resources: - - pulsartopics/finalizers + - pulsarsources/finalizers verbs: - update - apiGroups: - resource.streamnative.io resources: - - pulsartopics/status + - pulsarsources/status verbs: - get - patch @@ -177,7 +243,7 @@ rules: - apiGroups: - resource.streamnative.io resources: - - pulsargeoreplications + - pulsartenants verbs: - create - delete @@ -189,14 +255,41 @@ rules: - apiGroups: - resource.streamnative.io resources: - - pulsargeoreplications/finalizers + - pulsartenants/finalizers verbs: - update - apiGroups: - resource.streamnative.io resources: - - pulsargeoreplications/status + - pulsartenants/status verbs: - get - patch - - update \ No newline at end of file + - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsartopics + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsartopics/finalizers + verbs: + - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsartopics/status + verbs: + - get + - patch + - update + diff --git a/config/crd/bases/resource.streamnative.io_pulsarconnections.yaml b/config/crd/bases/resource.streamnative.io_pulsarconnections.yaml index 541e284c..b8ce0ad8 100644 --- a/config/crd/bases/resource.streamnative.io_pulsarconnections.yaml +++ b/config/crd/bases/resource.streamnative.io_pulsarconnections.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 StreamNative +# Copyright 2024 StreamNative # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: pulsarconnections.resource.streamnative.io spec: group: resource.streamnative.io @@ -65,14 +65,19 @@ spec: description: PulsarConnection is the Schema for the pulsarconnections API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -163,8 +168,9 @@ spec: pattern: ^pulsar?://.+$ type: string clusterName: - description: ClusterName indicates the local cluster name of the pulsar - cluster. It should set when enabling the Geo Replication + description: |- + ClusterName indicates the local cluster name of the pulsar cluster. It should + set when enabling the Geo Replication type: string type: object status: @@ -174,43 +180,49 @@ spec: description: Represents the observations of a connection's current state. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -224,11 +236,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -244,9 +257,9 @@ spec: - type x-kubernetes-list-type: map observedGeneration: - description: ObservedGeneration is the most recent generation observed - for this resource. It corresponds to the metadata generation, which - is updated on mutation by the API Server. + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. format: int64 type: integer secretKeyHash: @@ -258,9 +271,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crd/bases/resource.streamnative.io_pulsarfunctions.yaml b/config/crd/bases/resource.streamnative.io_pulsarfunctions.yaml new file mode 100644 index 00000000..1de5bcff --- /dev/null +++ b/config/crd/bases/resource.streamnative.io_pulsarfunctions.yaml @@ -0,0 +1,504 @@ +# Copyright 2024 StreamNative +# +# 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. + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: pulsarfunctions.resource.streamnative.io +spec: + group: resource.streamnative.io + names: + categories: + - pulsar + - pulsarres + kind: PulsarFunction + listKind: PulsarFunctionList + plural: pulsarfunctions + shortNames: + - pfunction + singular: pulsarfunction + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.name + name: RESOURCE_NAME + type: string + - jsonPath: .metadata.generation + name: GENERATION + type: string + - jsonPath: .status.observedGeneration + name: OBSERVED_GENERATION + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: READY + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: PulsarFunction is the Schema for the pulsar functions API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: PulsarFunctionSpec defines the desired state of PulsarFunction + properties: + autoAck: + description: AutoAck is the flag to indicate whether the function + should auto ack + type: boolean + batchBuilder: + description: BatchBuilder is the batch builder that the function uses + type: string + className: + description: ClassName is the class name of the function + type: string + cleanupSubscription: + description: CleanupSubscription is the flag to indicate whether the + subscription should be cleaned up when the function is deleted + type: boolean + connectionRef: + description: ConnectionRef is the reference to the PulsarConnection + resource + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + customRuntimeOptions: + description: CustomRuntimeOptions is the custom runtime options of + the function + x-kubernetes-preserve-unknown-fields: true + customSchemaInputs: + additionalProperties: + type: string + description: CustomSchemaInputs is the custom schema inputs of the + function + type: object + customSchemaOutputs: + additionalProperties: + type: string + description: CustomSchemaOutputs is the custom schema outputs of the + function + type: object + customSerdeInputs: + additionalProperties: + type: string + description: CustomSerdeInputs is the custom serde inputs of the function + type: object + deadLetterTopic: + description: DeadLetterTopic is the dead letter topic of the function + type: string + exposePulsarAdminClientEnabled: + description: ExposePulsarAdminClientEnabled is the flag to indicate + whether the function should expose pulsar admin client + type: boolean + forwardSourceMessageProperty: + description: ForwardSourceMessageProperty is the flag to indicate + whether the function should forward source message properties + type: boolean + go: + description: Go is the go of the function + properties: + url: + type: string + type: object + inputSpecs: + additionalProperties: + description: ConsumerConfig represents the configuration for the + consumer of the pulsar functions and connectors + properties: + consumerProperties: + additionalProperties: + type: string + type: object + cryptoConfig: + description: CryptoConfig represents the configuration for the + crypto of the pulsar functions and connectors + properties: + consumerCryptoFailureAction: + type: string + cryptoKeyReaderClassName: + type: string + cryptoKeyReaderConfig: + additionalProperties: + type: string + type: object + encryptionKeys: + items: + type: string + type: array + producerCryptoFailureAction: + type: string + required: + - consumerCryptoFailureAction + - cryptoKeyReaderClassName + - cryptoKeyReaderConfig + - encryptionKeys + - producerCryptoFailureAction + type: object + poolMessages: + type: boolean + receiverQueueSize: + type: integer + regexPattern: + type: boolean + schemaProperties: + additionalProperties: + type: string + type: object + schemaType: + type: string + serdeClassName: + type: string + type: object + description: InputSpecs is the input specs of the function + type: object + inputTypeClassName: + description: InputTypeClassName is the input type class name of the + function + type: string + inputs: + description: Inputs is the inputs of the function + items: + type: string + type: array + jar: + description: Jar is the jar of the function + properties: + url: + type: string + type: object + lifecyclePolicy: + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion + enum: + - CleanUpAfterDeletion + - KeepAfterDeletion + type: string + logTopic: + description: LogTopic is the log topic of the function + type: string + maxMessageRetries: + description: MaxMessageRetries is the max message retries of the function + type: integer + maxPendingAsyncRequests: + description: MaxPendingAsyncRequests is the max pending async requests + of the function + type: integer + name: + description: Name is the name of the function + type: string + namespace: + description: Namespace is the namespace of the function + type: string + output: + description: Output is the output of the function + type: string + outputSchemaType: + description: OutputSchemaType is the output schema type of the function + type: string + outputSerdeClassName: + description: OutputSerdeClassName is the output serde class name of + the function + type: string + outputTypeClassName: + description: OutputTypeClassName is the output type class name of + the function + type: string + parallelism: + description: Parallelism is the parallelism of the function + type: integer + processingGuarantees: + description: ProcessingGuarantees is the processing guarantees of + the function + type: string + producerConfig: + description: ProducerConfig is the producer config of the function + properties: + batchBuilder: + type: string + compressionType: + type: string + cryptoConfig: + description: CryptoConfig represents the configuration for the + crypto of the pulsar functions and connectors + properties: + consumerCryptoFailureAction: + type: string + cryptoKeyReaderClassName: + type: string + cryptoKeyReaderConfig: + additionalProperties: + type: string + type: object + encryptionKeys: + items: + type: string + type: array + producerCryptoFailureAction: + type: string + required: + - consumerCryptoFailureAction + - cryptoKeyReaderClassName + - cryptoKeyReaderConfig + - encryptionKeys + - producerCryptoFailureAction + type: object + maxPendingMessages: + type: integer + maxPendingMessagesAcrossPartitions: + type: integer + useThreadLocalProducers: + type: boolean + required: + - batchBuilder + - compressionType + - cryptoConfig + - maxPendingMessages + - maxPendingMessagesAcrossPartitions + - useThreadLocalProducers + type: object + py: + description: Py is the py of the function + properties: + url: + type: string + type: object + resources: + description: Resources is the resources of the function + properties: + cpu: + type: string + disk: + format: int64 + type: integer + ram: + format: int64 + type: integer + required: + - cpu + - disk + - ram + type: object + retainKeyOrdering: + description: RetainKeyOrdering is the flag to indicate whether the + function should retain key ordering + type: boolean + retainOrdering: + description: RetainOrdering is the flag to indicate whether the function + should retain ordering + type: boolean + runtimeFlags: + description: RuntimeFlags is the runtime flags of the function + type: string + secrets: + additionalProperties: + description: SecretKeyRef indicates a secret name and key + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + description: Secrets is the secrets of the function + type: object + skipToLatest: + description: SkipToLatest is the flag to indicate whether the function + should skip to latest + type: boolean + subName: + description: SubName is the sub name of the function + type: string + subscriptionPosition: + description: SubscriptionPosition is the subscription position of + the function + type: string + tenant: + description: Tenant is the tenant of the function + type: string + timeoutMs: + description: TimeoutMs is the function timeout in milliseconds + format: int64 + type: integer + topicsPattern: + description: TopicsPattern is the topics pattern that the function + subscribes to + type: string + userConfig: + description: UserConfig is the user config of the function + x-kubernetes-preserve-unknown-fields: true + windowConfig: + description: WindowConfig is the window config of the function + properties: + actualWindowFunctionClassName: + type: string + lateDataTopic: + type: string + maxLagMs: + format: int64 + type: integer + processingGuarantees: + type: string + slidingIntervalCount: + type: integer + slidingIntervalDurationMs: + format: int64 + type: integer + timestampExtractorClassName: + type: string + watermarkEmitIntervalMs: + format: int64 + type: integer + windowLengthCount: + type: integer + windowLengthDurationMs: + format: int64 + type: integer + required: + - actualWindowFunctionClassName + - lateDataTopic + - maxLagMs + - processingGuarantees + - slidingIntervalCount + - slidingIntervalDurationMs + - timestampExtractorClassName + - watermarkEmitIntervalMs + - windowLengthCount + - windowLengthDurationMs + type: object + required: + - connectionRef + type: object + status: + description: PulsarFunctionStatus defines the observed state of PulsarFunction + properties: + conditions: + description: Represents the observations of a connection's current + state. + items: + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/resource.streamnative.io_pulsargeoreplications.yaml b/config/crd/bases/resource.streamnative.io_pulsargeoreplications.yaml index 80fcc76a..03c7d2d6 100644 --- a/config/crd/bases/resource.streamnative.io_pulsargeoreplications.yaml +++ b/config/crd/bases/resource.streamnative.io_pulsargeoreplications.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 StreamNative +# Copyright 2024 StreamNative # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: pulsargeoreplications.resource.streamnative.io spec: group: resource.streamnative.io @@ -35,14 +35,19 @@ spec: API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -53,23 +58,30 @@ spec: description: ConnectionRef is the reference to the source PulsarConnection properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic destinationConnectionRef: description: DestinationConnectionRef is the connection reference to the remote cluster properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic lifecyclePolicy: - description: PulsarResourceLifeCyclePolicy indicates whether it will - keep or delete the resource in pulsar cluster after resource is - deleted by controller KeepAfterDeletion or CleanUpAfterDeletion + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion enum: - CleanUpAfterDeletion - KeepAfterDeletion @@ -86,43 +98,49 @@ spec: description: Conditions Represents the observations of a connection's current state. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -136,11 +154,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -156,9 +175,9 @@ spec: - type x-kubernetes-list-type: map observedGeneration: - description: ObservedGeneration is the most recent generation observed - for this resource. It corresponds to the metadata generation, which - is updated on mutation by the API Server. + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. format: int64 type: integer type: object @@ -167,9 +186,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crd/bases/resource.streamnative.io_pulsarnamespaces.yaml b/config/crd/bases/resource.streamnative.io_pulsarnamespaces.yaml index e542a3b0..c9855b7f 100644 --- a/config/crd/bases/resource.streamnative.io_pulsarnamespaces.yaml +++ b/config/crd/bases/resource.streamnative.io_pulsarnamespaces.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 StreamNative +# Copyright 2024 StreamNative # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: pulsarnamespaces.resource.streamnative.io spec: group: resource.streamnative.io @@ -52,14 +52,19 @@ spec: description: PulsarNamespace is the Schema for the pulsarnamespaces API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -73,14 +78,16 @@ spec: pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true backlogQuotaLimitTime: - description: Backlog Should set at least one of them if setting backlog + description: |- + Backlog + Should set at least one of them if setting backlog type: string backlogQuotaRetentionPolicy: type: string backlogQuotaType: - description: BacklogQuotaType controls the backlog by setting the - type to destination_storage or message_age destination_storage limits - backlog by size (in bytes). message_age limits backlog by time, + description: |- + BacklogQuotaType controls the backlog by setting the type to destination_storage or message_age + destination_storage limits backlog by size (in bytes). message_age limits backlog by time, that is, message timestamp (broker or publish timestamp) enum: - destination_storage @@ -94,27 +101,35 @@ spec: resource properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic geoReplicationRefs: description: GeoReplicationRefs is the reference list to the PulsarGeoReplication resource items: - description: LocalObjectReference contains enough information to - let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic type: array lifecyclePolicy: - description: PulsarResourceLifeCyclePolicy indicates whether it will - keep or delete the resource in pulsar cluster after resource is - deleted by controller KeepAfterDeletion or CleanUpAfterDeletion + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion enum: - CleanUpAfterDeletion - KeepAfterDeletion @@ -142,9 +157,10 @@ spec: pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true retentionTime: - description: Retention Should set at least one of them if setting - retention Retention Quota must exceed configured backlog quota for - namespace + description: |- + Retention + Should set at least one of them if setting retention + Retention Quota must exceed configured backlog quota for namespace type: string required: - connectionRef @@ -157,43 +173,49 @@ spec: description: Represents the observations of a connection's current state. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -207,11 +229,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -230,9 +253,9 @@ spec: description: GeoReplicationEnabled type: boolean observedGeneration: - description: ObservedGeneration is the most recent generation observed - for this resource. It corresponds to the metadata generation, which - is updated on mutation by the API Server. + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. format: int64 type: integer type: object @@ -241,9 +264,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crd/bases/resource.streamnative.io_pulsarpackages.yaml b/config/crd/bases/resource.streamnative.io_pulsarpackages.yaml new file mode 100644 index 00000000..eb3b62b8 --- /dev/null +++ b/config/crd/bases/resource.streamnative.io_pulsarpackages.yaml @@ -0,0 +1,210 @@ +# Copyright 2024 StreamNative +# +# 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. + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: pulsarpackages.resource.streamnative.io +spec: + group: resource.streamnative.io + names: + categories: + - pulsar + - pulsarres + kind: PulsarPackage + listKind: PulsarPackageList + plural: pulsarpackages + shortNames: + - ppackage + singular: pulsarpackage + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.name + name: RESOURCE_NAME + type: string + - jsonPath: .metadata.generation + name: GENERATION + type: string + - jsonPath: .status.observedGeneration + name: OBSERVED_GENERATION + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: READY + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: PulsarPackage is the Schema for the pulsar package management + service's package API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: PulsarPackageSpec defines the desired state of PulsarPackage + properties: + connectionRef: + description: ConnectionRef is the reference to the PulsarConnection + resource + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + contact: + type: string + description: + type: string + fileURL: + description: FileURL is the download-able URL of the package from + http or https protocol + type: string + lifecyclePolicy: + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion + enum: + - CleanUpAfterDeletion + - KeepAfterDeletion + type: string + packageURL: + description: PackageURL is the Pulsar Package URL, in format of type://tenant/namespace/package@version + type: string + properties: + additionalProperties: + type: string + type: object + required: + - connectionRef + - fileURL + - packageURL + type: object + status: + description: PulsarPackageStatus defines the observed state of PulsarPackage + properties: + conditions: + description: Represents the observations of a connection's current + state. + items: + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/resource.streamnative.io_pulsarpermissions.yaml b/config/crd/bases/resource.streamnative.io_pulsarpermissions.yaml index 532a729b..2ab07071 100644 --- a/config/crd/bases/resource.streamnative.io_pulsarpermissions.yaml +++ b/config/crd/bases/resource.streamnative.io_pulsarpermissions.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 StreamNative +# Copyright 2024 StreamNative # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: pulsarpermissions.resource.streamnative.io spec: group: resource.streamnative.io @@ -61,14 +61,19 @@ spec: description: PulsarPermission is the Schema for the pulsarpermissions API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -76,8 +81,9 @@ spec: description: PulsarPermissionSpec defines the desired state of PulsarPermission properties: actions: - description: Actions contains a list of action to grant. the options - include produce,consume,functions + description: |- + Actions contains a list of action to grant. + the options include produce,consume,functions items: type: string type: array @@ -86,13 +92,17 @@ spec: resource properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic lifecyclePolicy: - description: LifecyclePolicy is the policy that how to deal with pulsar - resource when PulsarPermission is deleted + description: |- + LifecyclePolicy is the policy that how to deal with pulsar resource when + PulsarPermission is deleted type: string resourceName: description: ResourceName name of the target resource which will be @@ -106,8 +116,9 @@ spec: - topic type: string roles: - description: Roles contains a list of role which will be granted the - same permissions for the same target + description: |- + Roles contains a list of role which will be granted the same permissions + for the same target items: type: string type: array @@ -124,43 +135,49 @@ spec: description: Represents the observations of a connection's current state. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -174,11 +191,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -194,9 +212,9 @@ spec: - type x-kubernetes-list-type: map observedGeneration: - description: ObservedGeneration is the most recent generation observed - for this resource. It corresponds to the metadata generation, which - is updated on mutation by the API Server. + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. format: int64 type: integer type: object @@ -205,9 +223,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crd/bases/resource.streamnative.io_pulsarsinks.yaml b/config/crd/bases/resource.streamnative.io_pulsarsinks.yaml new file mode 100644 index 00000000..fc0fe8a2 --- /dev/null +++ b/config/crd/bases/resource.streamnative.io_pulsarsinks.yaml @@ -0,0 +1,387 @@ +# Copyright 2024 StreamNative +# +# 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. + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: pulsarsinks.resource.streamnative.io +spec: + group: resource.streamnative.io + names: + categories: + - pulsar + - pulsarres + kind: PulsarSink + listKind: PulsarSinkList + plural: pulsarsinks + shortNames: + - psink + singular: pulsarsink + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.name + name: RESOURCE_NAME + type: string + - jsonPath: .metadata.generation + name: GENERATION + type: string + - jsonPath: .status.observedGeneration + name: OBSERVED_GENERATION + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: READY + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: PulsarSink is the Schema for the pulsar functions API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: PulsarSinkSpec defines the desired state of PulsarSink + properties: + archive: + description: Archive is the archive of the PulsarSink + properties: + url: + type: string + type: object + autoAck: + description: AutoAck is the flag to enable or disable the auto ack + type: boolean + className: + description: ClassName is the class name of the PulsarSink + type: string + cleanupSubscription: + description: CleanupSubscription is the flag to enable or disable + the cleanup of subscription + type: boolean + configs: + description: Configs is the map of configs of the PulsarSink + x-kubernetes-preserve-unknown-fields: true + connectionRef: + description: ConnectionRef is the reference to the PulsarConnection + resource + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + customRuntimeOptions: + description: CustomRuntimeOptions is the custom runtime options of + the PulsarSink + x-kubernetes-preserve-unknown-fields: true + deadLetterTopic: + description: DeadLetterTopic is the dead letter topic of the PulsarSink + type: string + inputSpecs: + additionalProperties: + description: ConsumerConfig represents the configuration for the + consumer of the pulsar functions and connectors + properties: + consumerProperties: + additionalProperties: + type: string + type: object + cryptoConfig: + description: CryptoConfig represents the configuration for the + crypto of the pulsar functions and connectors + properties: + consumerCryptoFailureAction: + type: string + cryptoKeyReaderClassName: + type: string + cryptoKeyReaderConfig: + additionalProperties: + type: string + type: object + encryptionKeys: + items: + type: string + type: array + producerCryptoFailureAction: + type: string + required: + - consumerCryptoFailureAction + - cryptoKeyReaderClassName + - cryptoKeyReaderConfig + - encryptionKeys + - producerCryptoFailureAction + type: object + poolMessages: + type: boolean + receiverQueueSize: + type: integer + regexPattern: + type: boolean + schemaProperties: + additionalProperties: + type: string + type: object + schemaType: + type: string + serdeClassName: + type: string + type: object + description: InputSpecs is the map of input specs of the PulsarSink + type: object + inputs: + description: Inputs is the list of inputs of the PulsarSink + items: + type: string + type: array + lifecyclePolicy: + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion + enum: + - CleanUpAfterDeletion + - KeepAfterDeletion + type: string + maxMessageRetries: + description: MaxMessageRetries is the max message retries of the PulsarSink + type: integer + name: + description: Name is the name of the PulsarSink + type: string + namespace: + description: Namespace is the namespace of the PulsarSink + type: string + negativeAckRedeliveryDelayMs: + description: NegativeAckRedeliveryDelayMs is the negative ack redelivery + delay in milliseconds of the PulsarSink + format: int64 + type: integer + parallelism: + description: Parallelism is the parallelism of the PulsarSink + type: integer + processingGuarantees: + description: ProcessingGuarantees is the processing guarantees of + the PulsarSink + type: string + resources: + description: Resources is the resource requirements for the PulsarSink + properties: + cpu: + type: string + disk: + format: int64 + type: integer + ram: + format: int64 + type: integer + required: + - cpu + - disk + - ram + type: object + retainKeyOrdering: + description: RetainKeyOrdering is the flag to enable or disable the + retain key ordering + type: boolean + retainOrdering: + description: RetainOrdering is the flag to enable or disable the retain + ordering + type: boolean + runtimeFlags: + description: RuntimeFlags is the runtime flags of the PulsarSink + type: string + secrets: + additionalProperties: + description: SecretKeyRef indicates a secret name and key + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + description: Secrets is the map of secrets of the PulsarSink + type: object + sinkType: + description: SinkType is the type of the PulsarSink + type: string + sourceSubscriptionName: + description: SourceSubscriptionName is the source subscription name + of the PulsarSink + type: string + sourceSubscriptionPosition: + description: SourceSubscriptionPosition is the source subscription + position of the PulsarSink + type: string + tenant: + description: Tenant is the tenant of the PulsarSink + type: string + timeoutMs: + description: TimeoutMs is the timeout in milliseconds for the PulsarSink + format: int64 + type: integer + topicToSchemaProperties: + additionalProperties: + type: string + description: TopicToSchemaProperties is the map of topic to schema + properties of the PulsarSink + type: object + topicToSchemaType: + additionalProperties: + type: string + description: TopicToSchemaType is the map of topic to schema type + of the PulsarSink + type: object + topicToSerdeClassName: + additionalProperties: + type: string + description: TopicToSerdeClassName is the map of topic to serde class + name of the PulsarSink + type: object + topicsPattern: + description: TopicsPattern is the pattern of topics to consume from + Pulsar + type: string + transformFunction: + description: TransformFunction is the transform function of the PulsarSink + type: string + transformFunctionClassName: + description: TransformFunctionClassName is the transform function + class name of the PulsarSink + type: string + transformFunctionConfig: + description: TransformFunctionConfig is the transform function config + of the PulsarSink + type: string + required: + - connectionRef + type: object + status: + description: PulsarSinkStatus defines the observed state of PulsarSink + properties: + conditions: + description: Represents the observations of a connection's current + state. + items: + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/resource.streamnative.io_pulsarsources.yaml b/config/crd/bases/resource.streamnative.io_pulsarsources.yaml new file mode 100644 index 00000000..fa165869 --- /dev/null +++ b/config/crd/bases/resource.streamnative.io_pulsarsources.yaml @@ -0,0 +1,326 @@ +# Copyright 2024 StreamNative +# +# 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. + +--- +apiVersion: apiextensions.k8s.io/v1 +kind: CustomResourceDefinition +metadata: + annotations: + controller-gen.kubebuilder.io/version: v0.15.0 + name: pulsarsources.resource.streamnative.io +spec: + group: resource.streamnative.io + names: + categories: + - pulsar + - pulsarres + kind: PulsarSource + listKind: PulsarSourceList + plural: pulsarsources + shortNames: + - psource + singular: pulsarsource + scope: Namespaced + versions: + - additionalPrinterColumns: + - jsonPath: .spec.name + name: RESOURCE_NAME + type: string + - jsonPath: .metadata.generation + name: GENERATION + type: string + - jsonPath: .status.observedGeneration + name: OBSERVED_GENERATION + type: string + - jsonPath: .status.conditions[?(@.type=="Ready")].status + name: READY + type: string + name: v1alpha1 + schema: + openAPIV3Schema: + description: PulsarSource is the Schema for the pulsar functions API + properties: + apiVersion: + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources + type: string + kind: + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds + type: string + metadata: + type: object + spec: + description: PulsarSourceSpec defines the desired state of PulsarSource + properties: + archive: + description: Archive is the archive of the PulsarSource + properties: + url: + type: string + type: object + batchBuilder: + description: BatchBuilder is the batch builder of the PulsarSource + type: string + batchSourceConfig: + description: BatchSourceConfig is the batch source config of the PulsarSource + properties: + discoveryTriggererClassName: + type: string + discoveryTriggererConfig: + x-kubernetes-preserve-unknown-fields: true + required: + - discoveryTriggererClassName + - discoveryTriggererConfig + type: object + className: + description: ClassName is the class name of the + type: string + configs: + description: Configs is the map of configs of the PulsarSource + x-kubernetes-preserve-unknown-fields: true + connectionRef: + description: ConnectionRef is the reference to the PulsarConnection + resource + properties: + name: + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? + type: string + type: object + x-kubernetes-map-type: atomic + customRuntimeOptions: + description: CustomRuntimeOptions is the custom runtime options of + the PulsarSource + x-kubernetes-preserve-unknown-fields: true + lifecyclePolicy: + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion + enum: + - CleanUpAfterDeletion + - KeepAfterDeletion + type: string + name: + description: Name is the name of the PulsarSource + type: string + namespace: + description: Namespace is the namespace of the PulsarSource + type: string + parallelism: + description: Parallelism is the parallelism of the PulsarSource + type: integer + processingGuarantees: + description: ProcessingGuarantees is the processing guarantees of + the PulsarSource + type: string + producerConfig: + description: ProducerConfig is the producer config of the PulsarSource + properties: + batchBuilder: + type: string + compressionType: + type: string + cryptoConfig: + description: CryptoConfig represents the configuration for the + crypto of the pulsar functions and connectors + properties: + consumerCryptoFailureAction: + type: string + cryptoKeyReaderClassName: + type: string + cryptoKeyReaderConfig: + additionalProperties: + type: string + type: object + encryptionKeys: + items: + type: string + type: array + producerCryptoFailureAction: + type: string + required: + - consumerCryptoFailureAction + - cryptoKeyReaderClassName + - cryptoKeyReaderConfig + - encryptionKeys + - producerCryptoFailureAction + type: object + maxPendingMessages: + type: integer + maxPendingMessagesAcrossPartitions: + type: integer + useThreadLocalProducers: + type: boolean + required: + - batchBuilder + - compressionType + - cryptoConfig + - maxPendingMessages + - maxPendingMessagesAcrossPartitions + - useThreadLocalProducers + type: object + resources: + description: Resources is the resources of the PulsarSource + properties: + cpu: + type: string + disk: + format: int64 + type: integer + ram: + format: int64 + type: integer + required: + - cpu + - disk + - ram + type: object + runtimeFlags: + description: RuntimeFlags is the runtime flags of the PulsarSource + type: string + schemaType: + description: SchemaType is the schema type of the PulsarSource + type: string + secrets: + additionalProperties: + description: SecretKeyRef indicates a secret name and key + properties: + key: + type: string + name: + type: string + required: + - key + - name + type: object + description: Secrets is the map of secrets of the PulsarSource + type: object + serdeClassName: + description: SerdeClassName is the serde class name of the PulsarSource + type: string + tenant: + description: Tenant is the tenant of the PulsarSource + type: string + topicName: + description: TopicName is the topic name of the PulsarSource + type: string + required: + - connectionRef + type: object + status: + description: PulsarSourceStatus defines the observed state of PulsarSource + properties: + conditions: + description: Represents the observations of a connection's current + state. + items: + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } + properties: + lastTransitionTime: + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. + format: date-time + type: string + message: + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. + maxLength: 32768 + type: string + observedGeneration: + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. + format: int64 + minimum: 0 + type: integer + reason: + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. + This field may not be empty. + maxLength: 1024 + minLength: 1 + pattern: ^[A-Za-z]([A-Za-z0-9_,:]*[A-Za-z0-9_])?$ + type: string + status: + description: status of the condition, one of True, False, Unknown. + enum: + - "True" + - "False" + - Unknown + type: string + type: + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + maxLength: 316 + pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ + type: string + required: + - lastTransitionTime + - message + - reason + - status + - type + type: object + type: array + x-kubernetes-list-map-keys: + - type + x-kubernetes-list-type: map + observedGeneration: + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. + format: int64 + type: integer + type: object + type: object + served: true + storage: true + subresources: + status: {} diff --git a/config/crd/bases/resource.streamnative.io_pulsartenants.yaml b/config/crd/bases/resource.streamnative.io_pulsartenants.yaml index a887dc11..d4d83ba4 100644 --- a/config/crd/bases/resource.streamnative.io_pulsartenants.yaml +++ b/config/crd/bases/resource.streamnative.io_pulsartenants.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 StreamNative +# Copyright 2024 StreamNative # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: pulsartenants.resource.streamnative.io spec: group: resource.streamnative.io @@ -52,14 +52,19 @@ spec: description: PulsarTenant is the Schema for the pulsartenants API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -79,27 +84,35 @@ spec: resource properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic geoReplicationRefs: description: GeoReplicationRefs is the reference list to the PulsarGeoReplication resource items: - description: LocalObjectReference contains enough information to - let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic type: array lifecyclePolicy: - description: PulsarResourceLifeCyclePolicy indicates whether it will - keep or delete the resource in pulsar cluster after resource is - deleted by controller KeepAfterDeletion or CleanUpAfterDeletion + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion enum: - CleanUpAfterDeletion - KeepAfterDeletion @@ -118,43 +131,49 @@ spec: description: Represents the observations of a connection's current state. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -168,11 +187,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -188,9 +208,9 @@ spec: - type x-kubernetes-list-type: map observedGeneration: - description: ObservedGeneration is the most recent generation observed - for this resource. It corresponds to the metadata generation, which - is updated on mutation by the API Server. + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. format: int64 type: integer type: object @@ -199,9 +219,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crd/bases/resource.streamnative.io_pulsartopics.yaml b/config/crd/bases/resource.streamnative.io_pulsartopics.yaml index 934bc9b9..09a384a1 100644 --- a/config/crd/bases/resource.streamnative.io_pulsartopics.yaml +++ b/config/crd/bases/resource.streamnative.io_pulsartopics.yaml @@ -1,4 +1,4 @@ -# Copyright 2023 StreamNative +# Copyright 2024 StreamNative # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. @@ -11,13 +11,13 @@ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. + --- apiVersion: apiextensions.k8s.io/v1 kind: CustomResourceDefinition metadata: annotations: - controller-gen.kubebuilder.io/version: v0.8.0 - creationTimestamp: null + controller-gen.kubebuilder.io/version: v0.15.0 name: pulsartopics.resource.streamnative.io spec: group: resource.streamnative.io @@ -52,14 +52,19 @@ spec: description: PulsarTopic is the Schema for the pulsartopics API properties: apiVersion: - description: 'APIVersion defines the versioned schema of this representation - of an object. Servers should convert recognized schemas to the latest - internal value, and may reject unrecognized values. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources' + description: |- + APIVersion defines the versioned schema of this representation of an object. + Servers should convert recognized schemas to the latest internal value, and + may reject unrecognized values. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#resources type: string kind: - description: 'Kind is a string value representing the REST resource this - object represents. Servers may infer this from the endpoint the client - submits requests to. Cannot be updated. In CamelCase. More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds' + description: |- + Kind is a string value representing the REST resource this object represents. + Servers may infer this from the endpoint the client submits requests to. + Cannot be updated. + In CamelCase. + More info: https://git.k8s.io/community/contributors/devel/sig-architecture/api-conventions.md#types-kinds type: string metadata: type: object @@ -73,7 +78,9 @@ spec: pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true backlogQuotaLimitTime: - description: Backlog Should set at least one of them if setting backlog + description: |- + Backlog + Should set at least one of them if setting backlog type: string backlogQuotaRetentionPolicy: type: string @@ -82,27 +89,35 @@ spec: resource properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic geoReplicationRefs: description: GeoReplicationRefs is the reference list to the PulsarGeoReplication resource items: - description: LocalObjectReference contains enough information to - let you locate the referenced object inside the same namespace. + description: |- + LocalObjectReference contains enough information to let you locate the + referenced object inside the same namespace. properties: name: - description: 'Name of the referent. More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names - TODO: Add other useful fields. apiVersion, kind, uid?' + description: |- + Name of the referent. + More info: https://kubernetes.io/docs/concepts/overview/working-with-objects/names/#names + TODO: Add other useful fields. apiVersion, kind, uid? type: string type: object + x-kubernetes-map-type: atomic type: array lifecyclePolicy: - description: PulsarResourceLifeCyclePolicy indicates whether it will - keep or delete the resource in pulsar cluster after resource is - deleted by controller KeepAfterDeletion or CleanUpAfterDeletion + description: |- + PulsarResourceLifeCyclePolicy indicates whether it will keep or delete the resource + in pulsar cluster after resource is deleted by controller + KeepAfterDeletion or CleanUpAfterDeletion enum: - CleanUpAfterDeletion - KeepAfterDeletion @@ -141,14 +156,15 @@ spec: pattern: ^(\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))(([KMGTPE]i)|[numkMGTPE]|([eE](\+|-)?(([0-9]+(\.[0-9]*)?)|(\.[0-9]+))))?$ x-kubernetes-int-or-string: true retentionTime: - description: Retention Should set at least one of them if setting - retention Retention Quota must exceed configured backlog quota for - topic + description: |- + Retention + Should set at least one of them if setting retention + Retention Quota must exceed configured backlog quota for topic type: string schemaInfo: - description: SchemaInfo defines the Pulsar Schema. It is stored and - enforced on a per-topic basis and cannot be stored at the namespace - or tenant level. + description: |- + SchemaInfo defines the Pulsar Schema. + It is stored and enforced on a per-topic basis and cannot be stored at the namespace or tenant level. properties: properties: additionalProperties: @@ -174,43 +190,49 @@ spec: description: Represents the observations of a connection's current state. items: - description: "Condition contains details for one aspect of the current - state of this API Resource. --- This struct is intended for direct - use as an array at the field path .status.conditions. For example, - type FooStatus struct{ // Represents the observations of a foo's - current state. // Known .status.conditions.type are: \"Available\", - \"Progressing\", and \"Degraded\" // +patchMergeKey=type // +patchStrategy=merge - // +listType=map // +listMapKey=type Conditions []metav1.Condition - `json:\"conditions,omitempty\" patchStrategy:\"merge\" patchMergeKey:\"type\" - protobuf:\"bytes,1,rep,name=conditions\"` \n // other fields }" + description: |- + Condition contains details for one aspect of the current state of this API Resource. + --- + This struct is intended for direct use as an array at the field path .status.conditions. For example, + type FooStatus struct{ + // Represents the observations of a foo's current state. + // Known .status.conditions.type are: "Available", "Progressing", and "Degraded" + // +patchMergeKey=type + // +patchStrategy=merge + // +listType=map + // +listMapKey=type + Conditions []metav1.Condition `json:"conditions,omitempty" patchStrategy:"merge" patchMergeKey:"type" protobuf:"bytes,1,rep,name=conditions"` + + + // other fields + } properties: lastTransitionTime: - description: lastTransitionTime is the last time the condition - transitioned from one status to another. This should be when - the underlying condition changed. If that is not known, then - using the time when the API field changed is acceptable. + description: |- + lastTransitionTime is the last time the condition transitioned from one status to another. + This should be when the underlying condition changed. If that is not known, then using the time when the API field changed is acceptable. format: date-time type: string message: - description: message is a human readable message indicating - details about the transition. This may be an empty string. + description: |- + message is a human readable message indicating details about the transition. + This may be an empty string. maxLength: 32768 type: string observedGeneration: - description: observedGeneration represents the .metadata.generation - that the condition was set based upon. For instance, if .metadata.generation - is currently 12, but the .status.conditions[x].observedGeneration - is 9, the condition is out of date with respect to the current - state of the instance. + description: |- + observedGeneration represents the .metadata.generation that the condition was set based upon. + For instance, if .metadata.generation is currently 12, but the .status.conditions[x].observedGeneration is 9, the condition is out of date + with respect to the current state of the instance. format: int64 minimum: 0 type: integer reason: - description: reason contains a programmatic identifier indicating - the reason for the condition's last transition. Producers - of specific condition types may define expected values and - meanings for this field, and whether the values are considered - a guaranteed API. The value should be a CamelCase string. + description: |- + reason contains a programmatic identifier indicating the reason for the condition's last transition. + Producers of specific condition types may define expected values and meanings for this field, + and whether the values are considered a guaranteed API. + The value should be a CamelCase string. This field may not be empty. maxLength: 1024 minLength: 1 @@ -224,11 +246,12 @@ spec: - Unknown type: string type: - description: type of condition in CamelCase or in foo.example.com/CamelCase. - --- Many .condition.type values are consistent across resources - like Available, but because arbitrary conditions can be useful - (see .node.status.conditions), the ability to deconflict is - important. The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) + description: |- + type of condition in CamelCase or in foo.example.com/CamelCase. + --- + Many .condition.type values are consistent across resources like Available, but because arbitrary conditions can be + useful (see .node.status.conditions), the ability to deconflict is important. + The regex it matches is (dns1123SubdomainFmt/)?(qualifiedNameFmt) maxLength: 316 pattern: ^([a-z0-9]([-a-z0-9]*[a-z0-9])?(\.[a-z0-9]([-a-z0-9]*[a-z0-9])?)*/)?(([A-Za-z0-9][-A-Za-z0-9_.]*)?[A-Za-z0-9])$ type: string @@ -247,9 +270,9 @@ spec: description: GeoReplicationEnabled type: boolean observedGeneration: - description: ObservedGeneration is the most recent generation observed - for this resource. It corresponds to the metadata generation, which - is updated on mutation by the API Server. + description: |- + ObservedGeneration is the most recent generation observed for this resource. + It corresponds to the metadata generation, which is updated on mutation by the API Server. format: int64 type: integer type: object @@ -258,9 +281,3 @@ spec: storage: true subresources: status: {} -status: - acceptedNames: - kind: "" - plural: "" - conditions: [] - storedVersions: [] diff --git a/config/crd/kustomization.yaml b/config/crd/kustomization.yaml index 06641497..956d7198 100644 --- a/config/crd/kustomization.yaml +++ b/config/crd/kustomization.yaml @@ -22,6 +22,10 @@ resources: - bases/resource.streamnative.io_pulsartopics.yaml - bases/resource.streamnative.io_pulsarpermissions.yaml - bases/resource.streamnative.io_pulsargeoreplications.yaml +- bases/resource.streamnative.io_pulsarfunctions.yaml +- bases/resource.streamnative.io_pulsarpackages.yaml +- bases/resource.streamnative.io_pulsarsinks.yaml +- bases/resource.streamnative.io_pulsarsources.yaml #+kubebuilder:scaffold:crdkustomizeresource patchesStrategicMerge: diff --git a/config/rbac/pulsarfunction_editor_role.yaml b/config/rbac/pulsarfunction_editor_role.yaml new file mode 100644 index 00000000..b89415f9 --- /dev/null +++ b/config/rbac/pulsarfunction_editor_role.yaml @@ -0,0 +1,38 @@ +# Copyright 2022 StreamNative +# +# 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. + +# permissions for end users to edit pulsartopics. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: pulsarfunction-editor-role +rules: +- apiGroups: + - resource.streamnative.io + resources: + - pulsarfunctions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsarfunctions/status + verbs: + - get diff --git a/config/rbac/pulsarfunction_viewer_role.yaml b/config/rbac/pulsarfunction_viewer_role.yaml new file mode 100644 index 00000000..6c22db60 --- /dev/null +++ b/config/rbac/pulsarfunction_viewer_role.yaml @@ -0,0 +1,34 @@ +# Copyright 2022 StreamNative +# +# 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. + +# permissions for end users to view pulsartopics. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: pulsarfunction-viewer-role +rules: +- apiGroups: + - resource.streamnative.io + resources: + - pulsarfunctions + verbs: + - get + - list + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsarfunctions/status + verbs: + - get diff --git a/config/rbac/pulsarpackage_editor_role.yaml b/config/rbac/pulsarpackage_editor_role.yaml new file mode 100644 index 00000000..c8d7f1e1 --- /dev/null +++ b/config/rbac/pulsarpackage_editor_role.yaml @@ -0,0 +1,38 @@ +# Copyright 2022 StreamNative +# +# 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. + +# permissions for end users to edit pulsartopics. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: pulsarpackage-editor-role +rules: +- apiGroups: + - resource.streamnative.io + resources: + - pulsarpackages + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsarpackages/status + verbs: + - get diff --git a/config/rbac/pulsarpackage_viewer_role.yaml b/config/rbac/pulsarpackage_viewer_role.yaml new file mode 100644 index 00000000..ab2454ba --- /dev/null +++ b/config/rbac/pulsarpackage_viewer_role.yaml @@ -0,0 +1,34 @@ +# Copyright 2022 StreamNative +# +# 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. + +# permissions for end users to view pulsartopics. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: pulsarpackage-viewer-role +rules: +- apiGroups: + - resource.streamnative.io + resources: + - pulsarpackages + verbs: + - get + - list + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsarpackages/status + verbs: + - get diff --git a/config/rbac/pulsarsink_editor_role.yaml b/config/rbac/pulsarsink_editor_role.yaml new file mode 100644 index 00000000..48e39338 --- /dev/null +++ b/config/rbac/pulsarsink_editor_role.yaml @@ -0,0 +1,38 @@ +# Copyright 2022 StreamNative +# +# 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. + +# permissions for end users to edit pulsartopics. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: pulsarsink-editor-role +rules: +- apiGroups: + - resource.streamnative.io + resources: + - pulsarsinks + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsarsinks/status + verbs: + - get diff --git a/config/rbac/pulsarsink_viewer_role.yaml b/config/rbac/pulsarsink_viewer_role.yaml new file mode 100644 index 00000000..1c5b10cd --- /dev/null +++ b/config/rbac/pulsarsink_viewer_role.yaml @@ -0,0 +1,34 @@ +# Copyright 2022 StreamNative +# +# 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. + +# permissions for end users to view pulsartopics. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: pulsarsink-viewer-role +rules: +- apiGroups: + - resource.streamnative.io + resources: + - pulsarsinks + verbs: + - get + - list + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsarsinks/status + verbs: + - get diff --git a/config/rbac/pulsarsource_editor_role.yaml b/config/rbac/pulsarsource_editor_role.yaml new file mode 100644 index 00000000..f2e0baa2 --- /dev/null +++ b/config/rbac/pulsarsource_editor_role.yaml @@ -0,0 +1,38 @@ +# Copyright 2022 StreamNative +# +# 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. + +# permissions for end users to edit pulsartopics. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: pulsarsource-editor-role +rules: +- apiGroups: + - resource.streamnative.io + resources: + - pulsarsources + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsarsources/status + verbs: + - get diff --git a/config/rbac/pulsarsource_viewer_role.yaml b/config/rbac/pulsarsource_viewer_role.yaml new file mode 100644 index 00000000..6af7bb85 --- /dev/null +++ b/config/rbac/pulsarsource_viewer_role.yaml @@ -0,0 +1,34 @@ +# Copyright 2022 StreamNative +# +# 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. + +# permissions for end users to view pulsartopics. +apiVersion: rbac.authorization.k8s.io/v1 +kind: ClusterRole +metadata: + name: pulsarsource-viewer-role +rules: +- apiGroups: + - resource.streamnative.io + resources: + - pulsarsources + verbs: + - get + - list + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsarsources/status + verbs: + - get diff --git a/config/rbac/role.yaml b/config/rbac/role.yaml index f4400ede..f43f67a2 100644 --- a/config/rbac/role.yaml +++ b/config/rbac/role.yaml @@ -1,21 +1,7 @@ -# Copyright 2023 StreamNative -# -# 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. --- apiVersion: rbac.authorization.k8s.io/v1 kind: ClusterRole metadata: - creationTimestamp: null name: manager-role rules: - apiGroups: @@ -56,6 +42,32 @@ rules: - get - patch - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsarfunctions + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsarfunctions/finalizers + verbs: + - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsarfunctions/status + verbs: + - get + - patch + - update - apiGroups: - resource.streamnative.io resources: @@ -108,6 +120,32 @@ rules: - get - patch - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsarpackages + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsarpackages/finalizers + verbs: + - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsarpackages/status + verbs: + - get + - patch + - update - apiGroups: - resource.streamnative.io resources: @@ -134,6 +172,58 @@ rules: - get - patch - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsarsinks + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsarsinks/finalizers + verbs: + - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsarsinks/status + verbs: + - get + - patch + - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsarsources + verbs: + - create + - delete + - get + - list + - patch + - update + - watch +- apiGroups: + - resource.streamnative.io + resources: + - pulsarsources/finalizers + verbs: + - update +- apiGroups: + - resource.streamnative.io + resources: + - pulsarsources/status + verbs: + - get + - patch + - update - apiGroups: - resource.streamnative.io resources: diff --git a/config/samples/kustomization.yaml b/config/samples/kustomization.yaml index 0e13793d..37ae67f8 100644 --- a/config/samples/kustomization.yaml +++ b/config/samples/kustomization.yaml @@ -20,4 +20,5 @@ resources: - resource_v1alpha1_pulsartopic.yaml - resource_v1alpha1_pulsarpermission.yaml - resource_v1alpha1_pulsargeoreplication.yaml +- resource_v1alpha1_pulsarpackage.yaml #+kubebuilder:scaffold:manifestskustomizesamples diff --git a/config/samples/resource_v1alpha1_pulsarfunction.yaml b/config/samples/resource_v1alpha1_pulsarfunction.yaml new file mode 100644 index 00000000..54f28f2f --- /dev/null +++ b/config/samples/resource_v1alpha1_pulsarfunction.yaml @@ -0,0 +1,52 @@ +# Copyright 2022 StreamNative +# +# 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. + +apiVersion: resource.streamnative.io/v1alpha1 +kind: PulsarFunction +metadata: + name: test-func + namespace: default +spec: + autoAck: true + className: org.apache.pulsar.functions.api.examples.ExclamationFunction + cleanupSubscription: true + connectionRef: + name: test-connection + customRuntimeOptions: {} + deadLetterTopic: dl-topic + exposePulsarAdminClientEnabled: false + forwardSourceMessageProperty: true + inputs: + - input + jar: + url: file:///pulsar/examples/api-examples.jar + lifecyclePolicy: CleanUpAfterDeletion + logTopic: func-log + maxMessageRetries: 101 + name: test-func + namespace: default + output: output + parallelism: 1 + processingGuarantees: ATLEAST_ONCE + retainKeyOrdering: true + retainOrdering: false + secrets: + SECRET1: + key: hello + name: sectest + skipToLatest: true + subName: test-sub + subscriptionPosition: Latest + tenant: public + timeoutMs: 6666 \ No newline at end of file diff --git a/config/samples/resource_v1alpha1_pulsarpackage.yaml b/config/samples/resource_v1alpha1_pulsarpackage.yaml new file mode 100644 index 00000000..55ebb781 --- /dev/null +++ b/config/samples/resource_v1alpha1_pulsarpackage.yaml @@ -0,0 +1,26 @@ +# Copyright 2022 StreamNative +# +# 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. + +apiVersion: resource.streamnative.io/v1alpha1 +kind: PulsarPackage +metadata: + name: pulsarpackage-sample + namespace: pulsar +spec: + packageURL: function://public/default/test@latest + fileURL: https://www.apache.org/dyn/mirrors/mirrors.cgi?action=download&filename=pulsar/pulsar-2.10.4/connectors/pulsar-io-file-2.10.4.nar + connectionRef: + name: pulsarconnection-sample + description: "test" + lifecyclePolicy: CleanUpAfterDeletion diff --git a/controllers/connection_ref_mapper.go b/controllers/connection_ref_mapper.go index cff4874c..6eed5c56 100644 --- a/controllers/connection_ref_mapper.go +++ b/controllers/connection_ref_mapper.go @@ -73,6 +73,14 @@ func getConnectionRef(object client.Object) *corev1.LocalObjectReference { return &v.Spec.ConnectionRef case *pulsarv1alpha1.PulsarGeoReplication: return &v.Spec.ConnectionRef + case *pulsarv1alpha1.PulsarFunction: + return &v.Spec.ConnectionRef + case *pulsarv1alpha1.PulsarSource: + return &v.Spec.ConnectionRef + case *pulsarv1alpha1.PulsarSink: + return &v.Spec.ConnectionRef + case *pulsarv1alpha1.PulsarPackage: + return &v.Spec.ConnectionRef default: return nil } diff --git a/controllers/pulsarconnection_controller.go b/controllers/pulsarconnection_controller.go index 862b4908..df651962 100644 --- a/controllers/pulsarconnection_controller.go +++ b/controllers/pulsarconnection_controller.go @@ -69,6 +69,18 @@ type PulsarConnectionReconciler struct { //+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsargeoreplications,verbs=get;list;watch;create;update;patch;delete //+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsargeoreplications/status,verbs=get;update;patch //+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsargeoreplications/finalizers,verbs=update +//+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsarpackages,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsarpackages/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsarpackages/finalizers,verbs=update +//+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsarfunctions,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsarfunctions/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsarfunctions/finalizers,verbs=update +//+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsarsinks,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsarsinks/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsarsinks/finalizers,verbs=update +//+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsarsources,verbs=get;list;watch;create;update;patch;delete +//+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsarsources/status,verbs=get;update;patch +//+kubebuilder:rbac:groups=resource.streamnative.io,resources=pulsarsources/finalizers,verbs=update //+kubebuilder:rbac:groups=core,resources=secrets,verbs=get;list;watch;create;update;patch;delete // Reconcile is part of the main kubernetes reconciliation loop which aims to @@ -95,6 +107,8 @@ func (r *PulsarConnectionReconciler) Reconcile(ctx context.Context, req ctrl.Req return reconcile.Result{}, nil } + r.Log.Info("Reconciling PulsarConnection", "name", pulsarConnection.Name, "namespace", pulsarConnection.Namespace) + reconciler := connection.MakeReconciler(r.Log, r.Client, r.PulsarAdminCreator, pulsarConnection) if err := reconciler.Observe(ctx); err != nil { return ctrl.Result{}, err @@ -159,6 +173,42 @@ func (r *PulsarConnectionReconciler) SetupWithManager(mgr ctrl.Manager, options return err } + if err := mgr.GetCache().IndexField(context.TODO(), &resourcev1alpha1.PulsarPackage{}, ".spec.connectionRef.name", + func(object client.Object) []string { + return []string{ + object.(*resourcev1alpha1.PulsarPackage).Spec.ConnectionRef.Name, + } + }); err != nil { + return err + } + + if err := mgr.GetCache().IndexField(context.TODO(), &resourcev1alpha1.PulsarFunction{}, ".spec.connectionRef.name", + func(object client.Object) []string { + return []string{ + object.(*resourcev1alpha1.PulsarFunction).Spec.ConnectionRef.Name, + } + }); err != nil { + return err + } + + if err := mgr.GetCache().IndexField(context.TODO(), &resourcev1alpha1.PulsarSink{}, ".spec.connectionRef.name", + func(object client.Object) []string { + return []string{ + object.(*resourcev1alpha1.PulsarSink).Spec.ConnectionRef.Name, + } + }); err != nil { + return err + } + + if err := mgr.GetCache().IndexField(context.TODO(), &resourcev1alpha1.PulsarSource{}, ".spec.connectionRef.name", + func(object client.Object) []string { + return []string{ + object.(*resourcev1alpha1.PulsarSource).Spec.ConnectionRef.Name, + } + }); err != nil { + return err + } + return ctrl.NewControllerManagedBy(mgr). For(&resourcev1alpha1.PulsarConnection{}). Watches(&source.Kind{Type: &resourcev1alpha1.PulsarTenant{}}, @@ -176,6 +226,18 @@ func (r *PulsarConnectionReconciler) SetupWithManager(mgr ctrl.Manager, options Watches(&source.Kind{Type: &resourcev1alpha1.PulsarGeoReplication{}}, handler.EnqueueRequestsFromMapFunc(ConnectionRefMapper), builder.WithPredicates(predicate.GenerationChangedPredicate{})). + Watches(&source.Kind{Type: &resourcev1alpha1.PulsarPackage{}}, + handler.EnqueueRequestsFromMapFunc(ConnectionRefMapper), + builder.WithPredicates(predicate.GenerationChangedPredicate{})). + Watches(&source.Kind{Type: &resourcev1alpha1.PulsarFunction{}}, + handler.EnqueueRequestsFromMapFunc(ConnectionRefMapper), + builder.WithPredicates(predicate.GenerationChangedPredicate{})). + Watches(&source.Kind{Type: &resourcev1alpha1.PulsarSink{}}, + handler.EnqueueRequestsFromMapFunc(ConnectionRefMapper), + builder.WithPredicates(predicate.GenerationChangedPredicate{})). + Watches(&source.Kind{Type: &resourcev1alpha1.PulsarSource{}}, + handler.EnqueueRequestsFromMapFunc(ConnectionRefMapper), + builder.WithPredicates(predicate.GenerationChangedPredicate{})). Watches(&source.Kind{Type: &corev1.Secret{}}, handler.EnqueueRequestsFromMapFunc(r.findSecretsForConnection), builder.WithPredicates(secretPredicate())). diff --git a/docs/pulsar_function.md b/docs/pulsar_function.md new file mode 100644 index 00000000..dbf0a7a0 --- /dev/null +++ b/docs/pulsar_function.md @@ -0,0 +1,171 @@ +# PulsarFunction + +## Create PulsarFunction + +1. Define a function named `test-pulsar-function` by using the YAML file and save the YAML file `function.yaml`. + +```yaml +apiVersion: resource.streamnative.io/v1alpha1 +kind: PulsarFunction +metadata: + name: test-pulsar-function + namespace: default +spec: + autoAck: true + className: org.apache.pulsar.functions.api.examples.ExclamationFunction + cleanupSubscription: true + connectionRef: + name: "test-pulsar-connection" + customRuntimeOptions: {} + deadLetterTopic: dl-topic + exposePulsarAdminClientEnabled: false + forwardSourceMessageProperty: true + inputs: + - input + jar: + url: function://public/default/api-examples@v3.2.3.3 + lifecyclePolicy: CleanUpAfterDeletion + logTopic: func-log + maxMessageRetries: 101 + name: test-pulsar-function + namespace: default + output: output + parallelism: 1 + processingGuarantees: ATLEAST_ONCE + retainKeyOrdering: true + retainOrdering: false + secrets: + SECRET1: + key: hello + name: sectest + skipToLatest: true + subName: test-sub + subscriptionPosition: Latest + tenant: public + timeoutMs: 6666 +``` + +This table lists specifications available for the `PulsarFunction` resource. + +| Option | Description | Required or not | +|----------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------| +| `autoAck` | Whether to automatically acknowledge messages. | Optional | +| `className` | The class name of the function. | Yes | +| `cleanupSubscription` | Whether to clean up the subscription when the function is deleted. | Optional | +| `connectionRef` | The reference to a PulsarConnection. | Yes | +| `customRuntimeOptions` | Custom runtime options. | Optional | +| `deadLetterTopic` | The dead letter topic. | Optional | +| `exposePulsarAdminClientEnabled` | Whether to expose the Pulsar admin client. | Optional | +| `forwardSourceMessageProperty` | Whether to forward the source message property. | Optional | +| `inputs` | The input topics. | Yes | +| `jar` | The JAR package URL, can be used by Java runtime. | Optional | +| `py` | The Python package URL, can be used by Java runtime. | Optional | +| `go` | The Go package URL, can be used by Java runtime. | Optional | +| `lifecyclePolicy` | The resource lifecycle policy. Available options are `CleanUpAfterDeletion` and `KeepAfterDeletion`. By default, it is set to `CleanUpAfterDeletion`. | Optional | +| `logTopic` | The log topic. | Optional | +| `maxMessageRetries` | The maximum number of message retries. | Optional | +| `name` | The function name. | Yes | +| `namespace` | The namespace. | Yes | +| `output` | The output topic. | Yes | +| `parallelism` | The parallelism. | Optional | +| `processingGuarantees` | The processing guarantees. | Optional | +| `retainKeyOrdering` | Whether to retain key ordering. | Optional | +| `retainOrdering` | Whether to retain ordering. | Optional | +| `secrets` | The secrets. | Optional | +| `skipToLatest` | Whether to skip to the latest. | Optional | +| `subName` | The subscription name. | Optional | +| `subscriptionPosition` | The subscription position. | Optional | +| `tenant` | The tenant. | Yes | +| `timeoutMs` | The timeout in milliseconds. | Optional | +| `topicsPattern` | The topics pattern. | Optional | +| `batchBuilder` | The batch builder. | Optional | +| `producerConfig` | The producer configuration. | Optional | +| `customSchemaOutputs` | The custom schema outputs. | Optional | +| `outputSerdeClassName` | The output serde class name. | Optional | +| `outputSchemaType` | The output schema type. | Optional | +| `outputTypeClassName` | The output type class name of the function. | Optional | +| `runtimeFlags` | The runtime flags. | Optional | +| `resources` | The resources. | Optional | +| `windowConfig` | The window configuration. | Optional | +| `userConfig` | The user configuration. | Optional | +| `customSerdeInputs` | The custom serde inputs. | Optional | +| `customSchemaInputs` | The custom schema inputs. | Optional | +| `inputSpecs` | The input specs. | Optional | +| `inputTypeClassName` | The input type class name of the function. | Optional | +| `maxPendingAsyncRequests` | The maximum number of pending async requests. | Optional | +| `exposePulsarAdminClientEnabled` | Whether to expose the Pulsar admin client. | Optional | +| `skipToLatest` | Whether to skip to the latest. | Optional | + +2. Apply the YAML file to create the function. + +```shell +kubectl apply -f function.yaml +``` + +3. Check the resource status. When column Ready is true, it indicates the resource is created successfully in the pulsar cluster + +```shell +kubectl get pulsarfunction +``` + +``` +NAME RESOURCE_NAME GENERATION OBSERVED_GENERATION READY +test-pulsar-function test-pulsar-function 1 1 True +``` + +## Update PulsarFunction + +You can update the function by editing the function.yaml, then apply it again. + +For example, if you want to update the parallelism of the function, you can edit the function.yaml as follows: + +```yaml +apiVersion: resource.streamnative.io/v1alpha1 +kind: PulsarFunction +metadata: + name: test-pulsar-function + namespace: default +spec: + autoAck: true + className: org.apache.pulsar.functions.api.examples.ExclamationFunction + cleanupSubscription: true + connectionRef: + name: "test-pulsar-connection" + customRuntimeOptions: {} + deadLetterTopic: dl-topic + exposePulsarAdminClientEnabled: false + forwardSourceMessageProperty: true + inputs: + - input + jar: + url: function://public/default/api-examples@v3.2.3.3 + lifecyclePolicy: CleanUpAfterDeletion + logTopic: func-log + maxMessageRetries: 101 + name: test-pulsar-function + namespace: default + output: output + parallelism: 2 + processingGuarantees: ATLEAST_ONCE + retainKeyOrdering: true + retainOrdering: false + secrets: + SECRET1: + key: hello + name: sectest + skipToLatest: true + subName: test-sub + subscriptionPosition: Latest + tenant: public + timeoutMs: 6666 +``` + +```shell +kubectl apply -f function.yaml +``` + +## Delete PulsarFunction + +```shell +kubectl delete pulsarfunction test-pulsar-function +``` diff --git a/docs/pulsar_package.md b/docs/pulsar_package.md new file mode 100644 index 00000000..85d43430 --- /dev/null +++ b/docs/pulsar_package.md @@ -0,0 +1,80 @@ +# PulsarPackage + +## Create PulsarPackage + +1. Define a package named `test-pulsar-package` by using the YAML file and save the YAML file `package.yaml`. +```yaml +apiVersion: resource.streamnative.io/v1alpha1 +kind: PulsarPackage +metadata: + name: test-pulsar-package + namespace: default +spec: + packageURL: function://public/default/api-examples@v3.2.3.3 + fileURL: https://github.com/freeznet/pulsar-functions-api-examples/raw/main/api-examples.jar + connectionRef: + name: "test-pulsar-connection" + description: api-examples.jar + lifecyclePolicy: CleanUpAfterDeletion +``` + +This table lists specifications available for the `PulsarPackage` resource. + +| Option | Description | Required or not | +| ---|-------------------------------------------------------------------------------------------------------------------------------------------------|--- | +| `packageURL` | The package URL. The information you provide creates a URL for a package, in the format ://///. | Yes | +| `fileURL` | The file URL that can be download from. | Yes | +| `connectionRef` | The reference to a PulsarConnection. | Yes | +| `description` | The description of the package. | Optional | +| `contact` | The contact information of the package. | Optional | +| `properties` | A user-defined key/value map to store other information. | Optional | +| `lifecyclePolicy` | The resource lifecycle policy. Available options are `CleanUpAfterDeletion` and `KeepAfterDeletion`. By default, it is set to `CleanUpAfterDeletion`. | Optional | + +2. Apply the YAML file to create the package. + +```shell +kubectl apply -f package.yaml +``` + +3. Check the resource status. When column Ready is true, it indicates the resource is created successfully in the pulsar cluster + +```shell +kubectl get pulsarpackage +``` + +``` +NAME RESOURCE_NAME GENERATION OBSERVED_GENERATION READY +test-pulsar-package 1 1 True +``` + +## Update PulsarPackage + +You can update the package by editing the package.yaml, then apply it again. For example, if you want to update the contact of the package, you can edit the package.yaml as follows: + +```yaml +apiVersion: resource.streamnative.io/v1alpha1 +kind: PulsarPackage +metadata: + name: test-pulsar-package + namespace: default +spec: + packageURL: function://public/default/api-examples@v3.2.3.3 + fileURL: https://github.com/freeznet/pulsar-functions-api-examples/raw/main/api-examples.jar + connectionRef: + name: "test-pulsar-connection" + description: api-examples.jar + contact: streamnative + lifecyclePolicy: CleanUpAfterDeletion +``` + +Please be noted that update will not overwrite the package content even if `fileURL` is changed. To change the package content, you need to create a new package. + +## Delete PulsarPackage + +You can delete the package by using the following command: + +```shell +kubectl delete pulsarpackage test-pulsar-package +``` + +Please be noticed, when you delete the package, the real package will still exist if the `lifecyclePolicy` is `KeepAfterDeletion`. diff --git a/docs/pulsar_sink.md b/docs/pulsar_sink.md new file mode 100644 index 00000000..f154b530 --- /dev/null +++ b/docs/pulsar_sink.md @@ -0,0 +1,135 @@ +# PulsarSink + +## Create PulsarSink + +1. Define a sink named `test-pulsar-sink` by using the YAML file and save the YAML file `sink.yaml`. + +```yaml +apiVersion: resource.streamnative.io/v1alpha1 +kind: PulsarSink +metadata: + name: test-pulsar-sink + namespace: default +spec: + autoAck: true + className: org.apache.pulsar.io.datagenerator.DataGeneratorPrintSink + cleanupSubscription: false + connectionRef: + name: "test-pulsar-connection" + customRuntimeOptions: {} + inputs: + - sink-input + archive: + url: builtin://data-generator + lifecyclePolicy: CleanUpAfterDeletion + name: test-pulsar-sink + namespace: default + parallelism: 1 + processingGuarantees: EFFECTIVELY_ONCE + secrets: + SECRET1: + key: hello + name: sectest + sourceSubscriptionPosition: Latest + tenant: public +``` + +This table lists specifications available for the `PulsarSink` resource. + +| Option | Description | Required or not | +|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------| +| `topicsPattern` | The topic pattern. | Optional | +| `resources` | The resources of the sink. | Optional | +| `timeoutMs` | The timeout in milliseconds. | Optional | +| `cleanupSubscription` | The cleanup subscription. | Optional | +| `retainOrdering` | The retain ordering. | Optional | +| `retainKeyOrdering` | The retain key ordering. | Optional | +| `autoAck` | The auto ack. | Optional | +| `parallelism` | The parallelism. | Optional | +| `tenant` | The tenant. | Required | +| `namespace` | The namespace. | Required | +| `name` | The name. | Required | +| `className` | The class name. | Required | +| `sinkType` | The sink type. | Optional | +| `archive` | The package url of sink. | Required | +| `processingGuarantees` | The processing guarantees. | Optional | +| `sourceSubscriptionName` | The source subscription name. | Optional | +| `sourceSubscriptionPosition` | The source subscription position. | Optional | +| `runtimeFlags` | The runtime flags. | Optional | +| `inputs` | The input topics. | Optional | +| `topicToSerdeClassName` | the map of topic to serde class name of the PulsarSink. | Optional | +| `topicToSchemaType` | the map of topic to schema type of the PulsarSink. | Optional | +| `inputSpecs` | the map of input specs of the PulsarSink. | Optional | +| `configs` | the map of configs of the PulsarSink. | Optional | +| `topicToSchemaProperties` | the map of topic to schema properties of the PulsarSink. | Optional | +| `customRuntimeOptions` | the map of custom runtime options of the PulsarSink. | Optional | +| `secrets` | the map of secrets of the PulsarSink. | Optional | +| `maxMessageRetries` | the max message retries of the PulsarSink. | Optional | +| `deadLetterTopic` | the dead letter topic of the PulsarSink. | Optional | +| `negativeAckRedeliveryDelayMs` | the negative ack redelivery delay in milliseconds of the PulsarSink. | Optional | +| `transformFunction` | the transform function of the PulsarSink. | Optional | +| `transformFunctionClassName` | the transform function class name of the PulsarSink. | Optional | +| `transformFunctionConfig` | the transform function config of the PulsarSink. | Optional | +| `connectionRef` | The reference to a PulsarConnection. | Required | +| `lifecyclePolicy` | The resource lifecycle policy. Available options are `CleanUpAfterDeletion` and `KeepAfterDeletion`. By default, it is set to `CleanUpAfterDeletion`. | Optional | + +2. Apply the YAML file to create the sink. + +```shell +kubectl apply -f sink.yaml +``` + +3. Check the resource status. When column Ready is true, it indicates the resource is created successfully in the pulsar cluster + +```shell +kubectl get pulsarsink +``` + +``` +NAME RESOURCE_NAME GENERATION OBSERVED_GENERATION READY +test-pulsar-sink test-pulsar-sink 2 2 True +``` + +## Update PulsarSink + +You can update the sink by editing the sink.yaml, then apply it again. For example, if you want to update the parallelism of the sink, you can edit the sink.yaml as follows: + +```yaml +apiVersion: resource.streamnative.io/v1alpha1 +kind: PulsarSink +metadata: + name: test-pulsar-sink + namespace: default +spec: + autoAck: true + className: org.apache.pulsar.io.datagenerator.DataGeneratorPrintSink + cleanupSubscription: false + connectionRef: + name: "test-pulsar-connection" + customRuntimeOptions: {} + inputs: + - sink-input + archive: + url: builtin://data-generator + lifecyclePolicy: CleanUpAfterDeletion + name: test-pulsar-sink + namespace: default + parallelism: 2 + processingGuarantees: EFFECTIVELY_ONCE + secrets: + SECRET1: + key: hello + name: sectest + sourceSubscriptionPosition: Latest + tenant: public +``` + +```shell +kubectl apply -f sink.yaml +``` + +## Delete PulsarSink + +```shell +kubectl delete pulsarsink test-pulsar-sink +``` diff --git a/docs/pulsar_source.md b/docs/pulsar_source.md new file mode 100644 index 00000000..527f4e84 --- /dev/null +++ b/docs/pulsar_source.md @@ -0,0 +1,119 @@ +# PulsarSource + +## Create PulsarSource + +1. Define a source named `test-pulsar-source` by using the YAML file and save the YAML file `source.yaml`. + +```yaml +apiVersion: resource.streamnative.io/v1alpha1 +kind: PulsarSource +metadata: + name: test-pulsar-source + namespace: default +spec: + className: org.apache.pulsar.io.datagenerator.DataGeneratorSource + connectionRef: + name: "test-pulsar-connection" + customRuntimeOptions: + sleepBetweenMessages: "1000" + topicName: sink-input + archive: + url: builtin://data-generator + configs: + sleepBetweenMessages: "1000" + lifecyclePolicy: CleanUpAfterDeletion + name: test-pulsar-source + namespace: default + parallelism: 1 + processingGuarantees: ATLEAST_ONCE + secrets: + SECRET1: + key: hello + name: sectest + tenant: public +``` + +This table lists specifications available for the `PulsarSource` resource. + +| Option | Description | Required or not | +|--------------------------------|-------------------------------------------------------------------------------------------------------------------------------------------------------|-----------------| +| `tenant` | The tenant. | Required | +| `namespace` | The namespace. | Required | +| `name` | The name. | Required | +| `className` | The class name. | Required | +| `producerConfig` | The producer config. | Optional | +| `topicName` | The topic name. | Required | +| `serdeClassName` | The serde class name. | Optional | +| `schemaType` | The schema type. | Optional | +| `configs` | The map of configs of the PulsarSource. | Optional | +| `secrets` | The map of secrets of the PulsarSource. | Optional | +| `parallelism` | The parallelism. | Optional | +| `processingGuarantees` | The processing guarantees. | Optional | +| `resources` | The resources of the source. | Optional | +| `archive` | The package url of source. | Required | +| `runtimeFlags` | The runtime flags. | Optional | +| `customRuntimeOptions` | The custom runtime options. | Optional | +| `batchSourceConfig` | The batch source config. | Optional | +| `batchBuilder` | The batch builder. | Optional | +| `connectionRef` | The reference to a PulsarConnection. | Required | +| `lifecyclePolicy` | The resource lifecycle policy. Available options are `CleanUpAfterDeletion` and `KeepAfterDeletion`. By default, it is set to `CleanUpAfterDeletion`. | Optional | + +2. Apply the YAML file to create the source. + +```shell +kubectl apply -f source.yaml +``` + +3. Check the resource status. When column Ready is true, it indicates the resource is created successfully in the pulsar cluster + +```shell +kubectl get pulsarsource +``` + +``` +NAME RESOURCE_NAME GENERATION OBSERVED_GENERATION READY +test-pulsar-source test-pulsar-source 1 1 True +``` + +## Update PulsarSource + +You can update the source by editing the source.yaml, then apply it again. For example, if you want to update the parallelism of the source, you can edit the source.yaml as follows: + +```yaml +apiVersion: resource.streamnative.io/v1alpha1 +kind: PulsarSource +metadata: + name: test-pulsar-source + namespace: default +spec: + className: org.apache.pulsar.io.datagenerator.DataGeneratorSource + connectionRef: + name: "test-pulsar-connection" + customRuntimeOptions: + sleepBetweenMessages: "1000" + topicName: sink-input + archive: + url: builtin://data-generator + configs: + sleepBetweenMessages: "1000" + lifecyclePolicy: CleanUpAfterDeletion + name: test-pulsar-source + namespace: default + parallelism: 2 + processingGuarantees: ATLEAST_ONCE + secrets: + SECRET1: + key: hello + name: sectest + tenant: public +``` + +```shell +kubectl apply -f source.yaml +``` + +## Delete PulsarSource + +```shell +kubectl delete pulsarsource test-pulsar-source +``` \ No newline at end of file diff --git a/go.mod b/go.mod index 3355b4d8..95515e2d 100644 --- a/go.mod +++ b/go.mod @@ -10,6 +10,7 @@ require ( github.com/xhit/go-str2duration/v2 v2.1.0 go.uber.org/zap v1.19.1 k8s.io/api v0.23.0 + k8s.io/apiextensions-apiserver v0.23.0 k8s.io/apimachinery v0.23.0 k8s.io/client-go v0.23.0 k8s.io/component-base v0.23.0 @@ -75,7 +76,6 @@ require ( gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 // indirect gopkg.in/yaml.v2 v2.4.0 // indirect gopkg.in/yaml.v3 v3.0.1 // indirect - k8s.io/apiextensions-apiserver v0.23.0 // indirect k8s.io/klog/v2 v2.30.0 // indirect k8s.io/kube-openapi v0.0.0-20211115234752-e816edb12b65 // indirect sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 // indirect diff --git a/pkg/admin/dummy.go b/pkg/admin/dummy.go index b6456b95..98cb8a04 100644 --- a/pkg/admin/dummy.go +++ b/pkg/admin/dummy.go @@ -128,3 +128,43 @@ func (d *DummyPulsarAdmin) DeleteCluster(string) error { func (d *DummyPulsarAdmin) CheckClusterExist(string) (bool, error) { return true, nil } + +// DeletePulsarPackage is a fake implements of DeletePulsarPackage +func (d *DummyPulsarAdmin) DeletePulsarPackage(_ string) error { + return nil +} + +// ApplyPulsarPackage is a fake implements of ApplyPulsarPackage +func (d *DummyPulsarAdmin) ApplyPulsarPackage(_, _, _, _ string, _ map[string]string, _ bool) error { + return nil +} + +// DeletePulsarFunction is a fake implements of DeletePulsarFunction +func (d *DummyPulsarAdmin) DeletePulsarFunction(_, _, _ string) error { + return nil +} + +// ApplyPulsarFunction is a fake implements of ApplyPulsarFunction +func (d *DummyPulsarAdmin) ApplyPulsarFunction(_, _, _, _ string, _ *v1alpha1.PulsarFunctionSpec, _ bool) error { + return nil +} + +// DeletePulsarSink is a fake implements of DeletePulsarSink +func (d *DummyPulsarAdmin) DeletePulsarSink(_, _, _ string) error { + return nil +} + +// ApplyPulsarSink is a fake implements of ApplyPulsarSink +func (d *DummyPulsarAdmin) ApplyPulsarSink(_, _, _, _ string, _ *v1alpha1.PulsarSinkSpec, _ bool) error { + return nil +} + +// DeletePulsarSource is a fake implements of DeletePulsarSource +func (d *DummyPulsarAdmin) DeletePulsarSource(_, _, _ string) error { + return nil +} + +// ApplyPulsarSource is a fake implements of ApplyPulsarSource +func (d *DummyPulsarAdmin) ApplyPulsarSource(_, _, _, _ string, _ *v1alpha1.PulsarSourceSpec, _ bool) error { + return nil +} diff --git a/pkg/admin/impl.go b/pkg/admin/impl.go index 30dd48bf..041b9c20 100644 --- a/pkg/admin/impl.go +++ b/pkg/admin/impl.go @@ -18,6 +18,7 @@ import ( "errors" "fmt" "os" + "strconv" "strings" "github.com/apache/pulsar-client-go/pulsaradmin/pkg/admin" @@ -26,6 +27,7 @@ import ( "k8s.io/utils/pointer" "github.com/streamnative/pulsar-resources-operator/api/v1alpha1" + rutils "github.com/streamnative/pulsar-resources-operator/pkg/utils" ) // PulsarAdminClient define the client to call pulsar @@ -654,3 +656,441 @@ func (p *PulsarAdminClient) CheckClusterExist(name string) (bool, error) { return true, nil } + +// DeletePulsarPackage deletes a pulsar package +func (p *PulsarAdminClient) DeletePulsarPackage(packageURL string) error { + return p.adminClient.Packages().Delete(packageURL) +} + +// ApplyPulsarPackage creates or updates a pulsar package +func (p *PulsarAdminClient) ApplyPulsarPackage(packageURL, filePath, description, contact string, properties map[string]string, changed bool) error { + packageName, err := utils.GetPackageName(packageURL) + if err != nil { + return err + } + if changed { + err = p.adminClient.Packages().UpdateMetadata(packageName.String(), description, contact, properties) + } else { + err = p.adminClient.Packages().Upload(packageName.String(), filePath, description, contact, properties) + } + if err != nil { + if !IsAlreadyExist(err) { + return err + } + } + + return nil +} + +// DeletePulsarFunction deletes a pulsar function +func (p *PulsarAdminClient) DeletePulsarFunction(tenant, namespace, name string) error { + return p.adminClient.Functions().DeleteFunction(tenant, namespace, name) +} + +// ApplyPulsarFunction creates or updates a pulsar function +func (p *PulsarAdminClient) ApplyPulsarFunction(tenant, namespace, name, packageURL string, param *v1alpha1.PulsarFunctionSpec, changed bool) error { + functionConfig := utils.FunctionConfig{ + Tenant: tenant, + Namespace: namespace, + Name: name, + ClassName: param.ClassName, + Inputs: param.Inputs, + Parallelism: param.Parallelism, + TimeoutMs: param.TimeoutMs, + TopicsPattern: param.TopicsPattern, + CleanupSubscription: param.CleanupSubscription, + RetainOrdering: param.RetainOrdering, + RetainKeyOrdering: param.RetainKeyOrdering, + ForwardSourceMessageProperty: param.ForwardSourceMessageProperty, + AutoAck: param.AutoAck, + MaxMessageRetries: param.MaxMessageRetries, + CustomSerdeInputs: param.CustomSerdeInputs, + CustomSchemaInputs: param.CustomSchemaInputs, + InputTypeClassName: param.InputTypeClassName, + Output: param.Output, + OutputSerdeClassName: param.OutputSerdeClassName, + OutputSchemaType: param.OutputSchemaType, + OutputTypeClassName: param.OutputTypeClassName, + CustomSchemaOutputs: param.CustomSchemaOutputs, + LogTopic: param.LogTopic, + ProcessingGuarantees: param.ProcessingGuarantees, + DeadLetterTopic: param.DeadLetterTopic, + SubName: param.SubName, + RuntimeFlags: param.RuntimeFlags, + MaxPendingAsyncRequests: param.MaxPendingAsyncRequests, + ExposePulsarAdminClientEnabled: param.ExposePulsarAdminClientEnabled, + SkipToLatest: param.SkipToLatest, + SubscriptionPosition: param.SubscriptionPosition, + } + + if param.BatchBuilder != nil { + functionConfig.BatchBuilder = *param.BatchBuilder + } + + if param.ProducerConfig != nil { + functionConfig.ProducerConfig = &utils.ProducerConfig{ + MaxPendingMessages: param.ProducerConfig.MaxPendingMessages, + MaxPendingMessagesAcrossPartitions: param.ProducerConfig.MaxPendingMessagesAcrossPartitions, + UseThreadLocalProducers: param.ProducerConfig.UseThreadLocalProducers, + BatchBuilder: param.ProducerConfig.BatchBuilder, + CompressionType: param.ProducerConfig.CompressionType, + } + if param.ProducerConfig.CryptoConfig != nil { + functionConfig.ProducerConfig.CryptoConfig = &utils.CryptoConfig{ + CryptoKeyReaderClassName: param.ProducerConfig.CryptoConfig.CryptoKeyReaderClassName, + CryptoKeyReaderConfig: rutils.ConvertMap(param.ProducerConfig.CryptoConfig.CryptoKeyReaderConfig), + EncryptionKeys: param.ProducerConfig.CryptoConfig.EncryptionKeys, + ProducerCryptoFailureAction: param.ProducerConfig.CryptoConfig.ProducerCryptoFailureAction, + ConsumerCryptoFailureAction: param.ProducerConfig.CryptoConfig.ConsumerCryptoFailureAction, + } + } + } + + if param.InputSpecs != nil && len(param.InputSpecs) > 0 { + inputSpecs := make(map[string]utils.ConsumerConfig) + for k, v := range param.InputSpecs { + iSpec := utils.ConsumerConfig{ + SchemaType: v.SchemaType, + SerdeClassName: v.SerdeClassName, + RegexPattern: v.RegexPattern, + ReceiverQueueSize: v.ReceiverQueueSize, + SchemaProperties: v.SchemaProperties, + ConsumerProperties: v.ConsumerProperties, + PoolMessages: v.PoolMessages, + } + if v.CryptoConfig != nil { + iSpec.CryptoConfig = &utils.CryptoConfig{ + CryptoKeyReaderClassName: v.CryptoConfig.CryptoKeyReaderClassName, + CryptoKeyReaderConfig: rutils.ConvertMap(v.CryptoConfig.CryptoKeyReaderConfig), + EncryptionKeys: v.CryptoConfig.EncryptionKeys, + ProducerCryptoFailureAction: v.CryptoConfig.ProducerCryptoFailureAction, + ConsumerCryptoFailureAction: v.CryptoConfig.ConsumerCryptoFailureAction, + } + } + inputSpecs[k] = iSpec + } + functionConfig.InputSpecs = inputSpecs + } + + if param.Resources != nil { + s, err := strconv.ParseFloat(param.Resources.CPU, 64) + if err != nil { + return err + } + functionConfig.Resources = &utils.Resources{ + CPU: s, + RAM: param.Resources.RAM, + Disk: param.Resources.Disk, + } + } + + if param.WindowConfig != nil { + functionConfig.WindowConfig = &utils.WindowConfig{ + WindowLengthCount: param.WindowConfig.WindowLengthCount, + WindowLengthDurationMs: param.WindowConfig.WindowLengthDurationMs, + SlidingIntervalCount: param.WindowConfig.SlidingIntervalCount, + SlidingIntervalDurationMs: param.WindowConfig.SlidingIntervalDurationMs, + LateDataTopic: param.WindowConfig.LateDataTopic, + MaxLagMs: param.WindowConfig.MaxLagMs, + WatermarkEmitIntervalMs: param.WindowConfig.WatermarkEmitIntervalMs, + TimestampExtractorClassName: param.WindowConfig.TimestampExtractorClassName, + ActualWindowFunctionClassName: param.WindowConfig.ActualWindowFunctionClassName, + ProcessingGuarantees: param.WindowConfig.ProcessingGuarantees, + } + } + + if param.UserConfig != nil { + var err error + functionConfig.UserConfig, err = rutils.ConvertJSONToMapStringInterface(param.UserConfig) + if err != nil { + return err + } + } + + if param.CustomRuntimeOptions != nil { + jByte, err := param.CustomRuntimeOptions.MarshalJSON() + if err != nil { + return err + } + functionConfig.CustomRuntimeOptions = string(jByte) + } + + if param.Secrets != nil && len(param.Secrets) > 0 { + secrets := make(map[string]interface{}) + for k, v := range param.Secrets { + secrets[k] = v + } + functionConfig.Secrets = secrets + } + + if param.Jar != nil { + functionConfig.Jar = &packageURL + } else if param.Py != nil { + functionConfig.Py = &packageURL + } else if param.Go != nil { + functionConfig.Go = &packageURL + } else { + return errors.New("FunctionConfig need to specify Jar, Py, or Go package URL") + } + + var err error + if changed { + err = p.adminClient.Functions().UpdateFunctionWithURL(&functionConfig, packageURL, nil) + } else { + err = p.adminClient.Functions().CreateFuncWithURL(&functionConfig, packageURL) + } + if err != nil { + if !IsAlreadyExist(err) { + return err + } + } + + return nil +} + +// DeletePulsarSink deletes a pulsar sink +func (p *PulsarAdminClient) DeletePulsarSink(tenant, namespace, name string) error { + return p.adminClient.Sinks().DeleteSink(tenant, namespace, name) +} + +// ApplyPulsarSink creates or updates a pulsar sink +func (p *PulsarAdminClient) ApplyPulsarSink(tenant, namespace, name, packageURL string, param *v1alpha1.PulsarSinkSpec, changed bool) error { + sinkConfig := utils.SinkConfig{ + Tenant: tenant, + Namespace: namespace, + Name: name, + ClassName: param.ClassName, + + TopicsPattern: param.TopicsPattern, + TimeoutMs: param.TimeoutMs, + + CleanupSubscription: param.CleanupSubscription, + RetainOrdering: param.RetainOrdering, + RetainKeyOrdering: param.RetainKeyOrdering, + AutoAck: param.AutoAck, + Parallelism: param.Parallelism, + + SinkType: param.SinkType, + Archive: packageURL, + + ProcessingGuarantees: param.ProcessingGuarantees, + SourceSubscriptionName: param.SourceSubscriptionName, + SourceSubscriptionPosition: param.SourceSubscriptionPosition, + RuntimeFlags: param.RuntimeFlags, + + Inputs: param.Inputs, + TopicToSerdeClassName: param.TopicToSerdeClassName, + TopicToSchemaType: param.TopicToSchemaType, + TopicToSchemaProperties: param.TopicToSchemaProperties, + + MaxMessageRetries: param.MaxMessageRetries, + DeadLetterTopic: param.DeadLetterTopic, + NegativeAckRedeliveryDelayMs: param.NegativeAckRedeliveryDelayMs, + TransformFunction: param.TransformFunction, + TransformFunctionClassName: param.TransformFunctionClassName, + TransformFunctionConfig: param.TransformFunctionConfig, + } + + if param.Resources != nil { + s, err := strconv.ParseFloat(param.Resources.CPU, 64) + if err != nil { + return err + } + sinkConfig.Resources = &utils.Resources{ + CPU: s, + RAM: param.Resources.RAM, + Disk: param.Resources.Disk, + } + } + + if param.InputSpecs != nil && len(param.InputSpecs) > 0 { + inputSpecs := make(map[string]utils.ConsumerConfig) + for k, v := range param.InputSpecs { + iSpec := utils.ConsumerConfig{ + SchemaType: v.SchemaType, + SerdeClassName: v.SerdeClassName, + RegexPattern: v.RegexPattern, + ReceiverQueueSize: v.ReceiverQueueSize, + SchemaProperties: v.SchemaProperties, + ConsumerProperties: v.ConsumerProperties, + PoolMessages: v.PoolMessages, + } + if v.CryptoConfig != nil { + iSpec.CryptoConfig = &utils.CryptoConfig{ + CryptoKeyReaderClassName: v.CryptoConfig.CryptoKeyReaderClassName, + CryptoKeyReaderConfig: rutils.ConvertMap(v.CryptoConfig.CryptoKeyReaderConfig), + EncryptionKeys: v.CryptoConfig.EncryptionKeys, + ProducerCryptoFailureAction: v.CryptoConfig.ProducerCryptoFailureAction, + ConsumerCryptoFailureAction: v.CryptoConfig.ConsumerCryptoFailureAction, + } + } + inputSpecs[k] = iSpec + } + sinkConfig.InputSpecs = inputSpecs + } + + if param.Configs != nil { + var err error + sinkConfig.Configs, err = rutils.ConvertJSONToMapStringInterface(param.Configs) + if err != nil { + return err + } + } + + if param.CustomRuntimeOptions != nil { + jByte, err := param.CustomRuntimeOptions.MarshalJSON() + if err != nil { + return err + } + sinkConfig.CustomRuntimeOptions = string(jByte) + } + + if param.Secrets != nil && len(param.Secrets) > 0 { + secrets := make(map[string]interface{}) + for k, v := range param.Secrets { + secrets[k] = v + } + sinkConfig.Secrets = secrets + } + + var err error + if changed { + if strings.HasPrefix(packageURL, "builtin://") { + err = p.adminClient.Sinks().UpdateSink(&sinkConfig, packageURL, nil) + } else { + err = p.adminClient.Sinks().UpdateSinkWithURL(&sinkConfig, packageURL, nil) + } + } else { + if strings.HasPrefix(packageURL, "builtin://") { + err = p.adminClient.Sinks().CreateSink(&sinkConfig, packageURL) + } else { + err = p.adminClient.Sinks().CreateSinkWithURL(&sinkConfig, packageURL) + } + } + if err != nil { + if !IsAlreadyExist(err) { + return err + } + } + + return nil +} + +// DeletePulsarSource deletes a pulsar source +func (p *PulsarAdminClient) DeletePulsarSource(tenant, namespace, name string) error { + return p.adminClient.Sources().DeleteSource(tenant, namespace, name) +} + +// ApplyPulsarSource creates or updates a pulsar source +func (p *PulsarAdminClient) ApplyPulsarSource(tenant, namespace, name, packageURL string, param *v1alpha1.PulsarSourceSpec, changed bool) error { + sourceConfig := utils.SourceConfig{ + Tenant: tenant, + Namespace: namespace, + Name: name, + ClassName: param.ClassName, + + TopicName: param.TopicName, + SerdeClassName: param.SerdeClassName, + SchemaType: param.SchemaType, + + Parallelism: param.Parallelism, + ProcessingGuarantees: param.ProcessingGuarantees, + + Archive: packageURL, + + RuntimeFlags: param.RuntimeFlags, + + BatchBuilder: param.BatchBuilder, + } + + if param.Resources != nil { + s, err := strconv.ParseFloat(param.Resources.CPU, 64) + if err != nil { + return err + } + sourceConfig.Resources = &utils.Resources{ + CPU: s, + RAM: param.Resources.RAM, + Disk: param.Resources.Disk, + } + } + + if param.ProducerConfig != nil { + sourceConfig.ProducerConfig = &utils.ProducerConfig{ + MaxPendingMessages: param.ProducerConfig.MaxPendingMessages, + MaxPendingMessagesAcrossPartitions: param.ProducerConfig.MaxPendingMessagesAcrossPartitions, + UseThreadLocalProducers: param.ProducerConfig.UseThreadLocalProducers, + BatchBuilder: param.ProducerConfig.BatchBuilder, + CompressionType: param.ProducerConfig.CompressionType, + } + if param.ProducerConfig.CryptoConfig != nil { + sourceConfig.ProducerConfig.CryptoConfig = &utils.CryptoConfig{ + CryptoKeyReaderClassName: param.ProducerConfig.CryptoConfig.CryptoKeyReaderClassName, + CryptoKeyReaderConfig: rutils.ConvertMap(param.ProducerConfig.CryptoConfig.CryptoKeyReaderConfig), + EncryptionKeys: param.ProducerConfig.CryptoConfig.EncryptionKeys, + ProducerCryptoFailureAction: param.ProducerConfig.CryptoConfig.ProducerCryptoFailureAction, + ConsumerCryptoFailureAction: param.ProducerConfig.CryptoConfig.ConsumerCryptoFailureAction, + } + } + } + + if param.BatchSourceConfig != nil { + sourceConfig.BatchSourceConfig = &utils.BatchSourceConfig{ + DiscoveryTriggererClassName: param.BatchSourceConfig.DiscoveryTriggererClassName, + } + if param.BatchSourceConfig.DiscoveryTriggererConfig != nil { + var err error + sourceConfig.BatchSourceConfig.DiscoveryTriggererConfig, err = rutils.ConvertJSONToMapStringInterface(param.BatchSourceConfig.DiscoveryTriggererConfig) + if err != nil { + return err + } + } + } + + if param.Configs != nil { + var err error + sourceConfig.Configs, err = rutils.ConvertJSONToMapStringInterface(param.Configs) + if err != nil { + return err + } + } + + if param.Secrets != nil && len(param.Secrets) > 0 { + secrets := make(map[string]interface{}) + for k, v := range param.Secrets { + secrets[k] = v + } + sourceConfig.Secrets = secrets + } + + if param.CustomRuntimeOptions != nil { + jByte, err := param.CustomRuntimeOptions.MarshalJSON() + if err != nil { + return err + } + sourceConfig.CustomRuntimeOptions = string(jByte) + } + + var err error + + if changed { + if strings.HasPrefix(packageURL, "builtin://") { + err = p.adminClient.Sources().UpdateSource(&sourceConfig, packageURL, nil) + } else { + err = p.adminClient.Sources().UpdateSourceWithURL(&sourceConfig, packageURL, nil) + } + } else { + if strings.HasPrefix(packageURL, "builtin://") { + err = p.adminClient.Sources().CreateSource(&sourceConfig, packageURL) + } else { + err = p.adminClient.Sources().CreateSourceWithURL(&sourceConfig, packageURL) + } + } + if err != nil { + if !IsAlreadyExist(err) { + return err + } + } + + return nil +} diff --git a/pkg/admin/interface.go b/pkg/admin/interface.go index e993e552..a72c80fd 100644 --- a/pkg/admin/interface.go +++ b/pkg/admin/interface.go @@ -151,6 +151,30 @@ type PulsarAdmin interface { // CheckClusterExist check wether the cluster is created or not CheckClusterExist(name string) (bool, error) + + // DeletePulsarPackage delete pulsar package + DeletePulsarPackage(packageURL string) error + + // ApplyPulsarPackage apply pulsar package + ApplyPulsarPackage(packageURL, filePath, description, contact string, properties map[string]string, changed bool) error + + // DeletePulsarFunction delete pulsar function + DeletePulsarFunction(tenant, namespace, name string) error + + // ApplyPulsarFunction apply pulsar function + ApplyPulsarFunction(tenant, namespace, name, packageURL string, param *v1alpha1.PulsarFunctionSpec, changed bool) error + + // DeletePulsarSink delete pulsar sink + DeletePulsarSink(tenant, namespace, name string) error + + // ApplyPulsarSink apply pulsar sink + ApplyPulsarSink(tenant, namespace, name, packageURL string, param *v1alpha1.PulsarSinkSpec, changed bool) error + + // DeletePulsarSource delete pulsar source + DeletePulsarSource(tenant, namespace, name string) error + + // ApplyPulsarSource apply pulsar source + ApplyPulsarSource(tenant, namespace, name, packageURL string, param *v1alpha1.PulsarSourceSpec, changed bool) error } // PulsarAdminCreator is the function type to create a PulsarAdmin with config @@ -179,6 +203,8 @@ type PulsarAdminConfig struct { Audience string Key string Scope string + + PulsarAPIVersion *config.APIVersion } // NewPulsarAdmin initialize a pulsar admin client with configuration @@ -195,6 +221,10 @@ func NewPulsarAdmin(conf PulsarAdminConfig) (PulsarAdmin, error) { PulsarAPIVersion: config.V2, } + if conf.PulsarAPIVersion != nil { + config.PulsarAPIVersion = *conf.PulsarAPIVersion + } + if conf.Key != "" { keyFile, err = ioutil.TempFile("", "oauth2-key-") if err != nil { diff --git a/pkg/connection/reconcile_function.go b/pkg/connection/reconcile_function.go new file mode 100644 index 00000000..ad0aefe0 --- /dev/null +++ b/pkg/connection/reconcile_function.go @@ -0,0 +1,173 @@ +// Copyright 2022 StreamNative +// +// 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 connection + +import ( + "context" + "errors" + "fmt" + "strings" + + "github.com/apache/pulsar-client-go/pulsaradmin/pkg/utils" + "github.com/go-logr/logr" + "github.com/streamnative/pulsar-resources-operator/pkg/feature" + "k8s.io/apimachinery/pkg/api/meta" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + + resourcev1alpha1 "github.com/streamnative/pulsar-resources-operator/api/v1alpha1" + "github.com/streamnative/pulsar-resources-operator/pkg/admin" + "github.com/streamnative/pulsar-resources-operator/pkg/reconciler" +) + +// PulsarFunctionReconciler reconciles a PulsarFunction object +type PulsarFunctionReconciler struct { + conn *PulsarConnectionReconciler + log logr.Logger +} + +func makeFunctionsReconciler(r *PulsarConnectionReconciler) reconciler.Interface { + return &PulsarFunctionReconciler{ + conn: r, + log: makeSubResourceLog(r, "PulsarFunction"), + } +} + +// Observe checks the updates of object +func (r *PulsarFunctionReconciler) Observe(ctx context.Context) error { + r.log.V(1).Info("Start Observe") + + functionsList := &resourcev1alpha1.PulsarFunctionList{} + if err := r.conn.client.List(ctx, functionsList, client.InNamespace(r.conn.connection.Namespace), + client.MatchingFields(map[string]string{ + ".spec.connectionRef.name": r.conn.connection.Name, + })); err != nil { + return fmt.Errorf("list functions [%w]", err) + } + r.log.V(1).Info("Observed function items", "Count", len(functionsList.Items)) + + r.conn.functions = functionsList.Items + for i := range r.conn.functions { + if !resourcev1alpha1.IsPulsarResourceReady(&r.conn.functions[i]) { + r.conn.addUnreadyResource(&r.conn.functions[i]) + } + } + + r.log.V(1).Info("Observe Done") + return nil +} + +// Reconcile reconciles all functions +func (r *PulsarFunctionReconciler) Reconcile(ctx context.Context) error { + for i := range r.conn.functions { + instance := &r.conn.functions[i] + if err := r.ReconcileFunction(ctx, r.conn.pulsarAdminV3, instance); err != nil { + return fmt.Errorf("reconcile pulsar function [%w]", err) + } + } + return nil +} + +// ReconcileFunction move the current state of the functions closer to the desired state +func (r *PulsarFunctionReconciler) ReconcileFunction(ctx context.Context, pulsarAdmin admin.PulsarAdmin, + instance *resourcev1alpha1.PulsarFunction) error { + log := r.log.WithValues("name", instance.Name, "namespace", instance.Namespace) + log.Info("Start Reconcile") + + if !instance.DeletionTimestamp.IsZero() { + log.Info("Deleting function", "LifecyclePolicy", instance.Spec.LifecyclePolicy) + + if instance.Spec.LifecyclePolicy != resourcev1alpha1.KeepAfterDeletion { + if err := pulsarAdmin.DeletePulsarFunction(instance.Spec.Tenant, instance.Spec.Namespace, instance.Spec.Name); err != nil && !admin.IsNotFound(err) { + log.Error(err, "Failed to delete function") + return err + } + } + + // TODO use otelcontroller until kube-instrumentation upgrade controller-runtime version to newer + controllerutil.RemoveFinalizer(instance, resourcev1alpha1.FinalizerName) + if err := r.conn.client.Update(ctx, instance); err != nil { + log.Error(err, "Failed to remove finalizer") + return err + } + return nil + } + + if instance.Spec.LifecyclePolicy != resourcev1alpha1.KeepAfterDeletion { + // TODO use otelcontroller until kube-instrumentation upgrade controller-runtime version to newer + controllerutil.AddFinalizer(instance, resourcev1alpha1.FinalizerName) + if err := r.conn.client.Update(ctx, instance); err != nil { + log.Error(err, "Failed to add finalizer") + return err + } + } + + if resourcev1alpha1.IsPulsarResourceReady(instance) && + !feature.DefaultFeatureGate.Enabled(feature.AlwaysUpdatePulsarResource) { + log.Info("Skip reconcile, function resource is ready") + return nil + } + + packageURL := "" + if instance.Spec.Jar != nil && instance.Spec.Jar.URL != "" { + packageURL = validateURL(instance.Spec.Jar.URL) + } else if instance.Spec.Py != nil && instance.Spec.Py.URL != "" { + packageURL = validateURL(instance.Spec.Py.URL) + } else if instance.Spec.Go != nil && instance.Spec.Go.URL != "" { + packageURL = validateURL(instance.Spec.Go.URL) + } else { + err := errors.New("no package URL found") + return err + } + + if packageURL == "" { + err := errors.New("invalid package URL") + return err + } + + if err := pulsarAdmin.ApplyPulsarFunction(instance.Spec.Tenant, instance.Spec.Namespace, instance.Spec.Name, packageURL, &instance.Spec, instance.Status.ObservedGeneration > 1); err != nil { + meta.SetStatusCondition(&instance.Status.Conditions, *NewErrorCondition(instance.Generation, err.Error())) + log.Error(err, "Failed to apply function") + if err := r.conn.client.Status().Update(ctx, instance); err != nil { + log.Error(err, "Failed to update the function status") + return nil + } + return err + } + + instance.Status.ObservedGeneration = instance.Generation + meta.SetStatusCondition(&instance.Status.Conditions, *NewReadyCondition(instance.Generation)) + if err := r.conn.client.Status().Update(ctx, instance); err != nil { + log.Error(err, "Failed to update the function status") + return err + } + return nil +} + +func validateURL(url string) string { + if url == "" { + return "" + } + if lowerURL := strings.ToLower(url); strings.HasPrefix(lowerURL, "http://") || + strings.HasPrefix(lowerURL, "https://") || + strings.HasPrefix(lowerURL, "builtin://") || + strings.HasPrefix(lowerURL, "file://") { + return url + } + if _, err := utils.GetPackageName(url); err != nil { + return "" + } + return url +} diff --git a/pkg/connection/reconcile_package.go b/pkg/connection/reconcile_package.go new file mode 100644 index 00000000..6028ad35 --- /dev/null +++ b/pkg/connection/reconcile_package.go @@ -0,0 +1,187 @@ +// Copyright 2022 StreamNative +// +// 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 connection + +import ( + "context" + "errors" + "fmt" + "io" + "net/http" + "net/url" + "os" + + "github.com/go-logr/logr" + "github.com/streamnative/pulsar-resources-operator/pkg/feature" + "k8s.io/apimachinery/pkg/api/meta" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" + + resourcev1alpha1 "github.com/streamnative/pulsar-resources-operator/api/v1alpha1" + "github.com/streamnative/pulsar-resources-operator/pkg/admin" + "github.com/streamnative/pulsar-resources-operator/pkg/reconciler" +) + +// PulsarPackageReconciler reconciles a PulsarPackage object +type PulsarPackageReconciler struct { + conn *PulsarConnectionReconciler + log logr.Logger +} + +func makePackagesReconciler(r *PulsarConnectionReconciler) reconciler.Interface { + return &PulsarPackageReconciler{ + conn: r, + log: makeSubResourceLog(r, "PulsarPackage"), + } +} + +// Observe checks the updates of object +func (r *PulsarPackageReconciler) Observe(ctx context.Context) error { + r.log.V(1).Info("Start Observe") + + packageList := &resourcev1alpha1.PulsarPackageList{} + if err := r.conn.client.List(ctx, packageList, client.InNamespace(r.conn.connection.Namespace), + client.MatchingFields(map[string]string{ + ".spec.connectionRef.name": r.conn.connection.Name, + })); err != nil { + return fmt.Errorf("list packages [%w]", err) + } + r.log.V(1).Info("Observed package items", "Count", len(packageList.Items)) + + r.conn.packages = packageList.Items + for i := range r.conn.packages { + if !resourcev1alpha1.IsPulsarResourceReady(&r.conn.packages[i]) { + r.conn.addUnreadyResource(&r.conn.packages[i]) + } + } + + r.log.V(1).Info("Observe Done") + return nil +} + +// Reconcile reconciles all topics +func (r *PulsarPackageReconciler) Reconcile(ctx context.Context) error { + for i := range r.conn.packages { + pkg := &r.conn.packages[i] + if err := r.ReconcilePackage(ctx, r.conn.pulsarAdminV3, pkg); err != nil { + return fmt.Errorf("reconcile pulsar package [%w]", err) + } + } + return nil +} + +// ReconcilePackage move the current state of the package closer to the desired state +func (r *PulsarPackageReconciler) ReconcilePackage(ctx context.Context, pulsarAdmin admin.PulsarAdmin, + pkg *resourcev1alpha1.PulsarPackage) error { + log := r.log.WithValues("name", pkg.Name, "namespace", pkg.Namespace) + log.Info("Start Reconcile") + + if !pkg.DeletionTimestamp.IsZero() { + log.Info("Deleting package", "LifecyclePolicy", pkg.Spec.LifecyclePolicy) + + if pkg.Spec.LifecyclePolicy != resourcev1alpha1.KeepAfterDeletion { + if err := pulsarAdmin.DeletePulsarPackage(pkg.Spec.PackageURL); err != nil && !admin.IsNotFound(err) { + log.Error(err, "Failed to delete package") + return err + } + } + + // TODO use otelcontroller until kube-instrumentation upgrade controller-runtime version to newer + controllerutil.RemoveFinalizer(pkg, resourcev1alpha1.FinalizerName) + if err := r.conn.client.Update(ctx, pkg); err != nil { + log.Error(err, "Failed to remove finalizer") + return err + } + return nil + } + + if pkg.Spec.LifecyclePolicy != resourcev1alpha1.KeepAfterDeletion { + // TODO use otelcontroller until kube-instrumentation upgrade controller-runtime version to newer + controllerutil.AddFinalizer(pkg, resourcev1alpha1.FinalizerName) + if err := r.conn.client.Update(ctx, pkg); err != nil { + log.Error(err, "Failed to add finalizer") + return err + } + } + + if resourcev1alpha1.IsPulsarResourceReady(pkg) && + !feature.DefaultFeatureGate.Enabled(feature.AlwaysUpdatePulsarResource) { + log.Info("Skip reconcile, package resource is ready") + return nil + } + + filePath, err := createTmpFile(pkg.Spec.FileURL) + if err != nil { + log.Error(err, "Failed to download the package file") + return err + } + defer os.Remove(filePath) + + if err := pulsarAdmin.ApplyPulsarPackage(pkg.Spec.PackageURL, filePath, pkg.Spec.Description, pkg.Spec.Contact, pkg.Spec.Properties, pkg.Status.ObservedGeneration > 1); err != nil { + meta.SetStatusCondition(&pkg.Status.Conditions, *NewErrorCondition(pkg.Generation, err.Error())) + log.Error(err, "Failed to apply package") + if err := r.conn.client.Status().Update(ctx, pkg); err != nil { + log.Error(err, "Failed to update the package status") + return nil + } + return err + } + + pkg.Status.ObservedGeneration = pkg.Generation + meta.SetStatusCondition(&pkg.Status.Conditions, *NewReadyCondition(pkg.Generation)) + if err := r.conn.client.Status().Update(ctx, pkg); err != nil { + log.Error(err, "Failed to update the package status") + return err + } + return nil +} + +func createTmpFile(fileURL string) (string, error) { + // get the file from the url and save it to a temp file + parsedURL, err := url.Parse(fileURL) + if err != nil { + return "", fmt.Errorf("invalid URL: %v", err) + } + + if parsedURL.Scheme != "http" && parsedURL.Scheme != "https" { + return "", errors.New("URL must be HTTP or HTTPS") + } + + // create a temporary file + tmpFile, err := os.CreateTemp("/tmp", "downloaded-*") + if err != nil { + return "", fmt.Errorf("failed to create temp file: %v", err) + } + defer tmpFile.Close() + + // make HTTP GET request to the URL + resp, err := http.Get(fileURL) //nolint:gosec + if err != nil { + return "", fmt.Errorf("failed to download file: %v", err) + } + defer resp.Body.Close() + + if resp.StatusCode != http.StatusOK { + return "", fmt.Errorf("download failed with status: %v", resp.Status) + } + + // copy the response body to the temp file + _, err = io.Copy(tmpFile, resp.Body) + if err != nil { + return "", fmt.Errorf("failed to write to temp file: %v", err) + } + + return tmpFile.Name(), nil +} diff --git a/pkg/connection/reconcile_sink.go b/pkg/connection/reconcile_sink.go new file mode 100644 index 00000000..7f9f47e6 --- /dev/null +++ b/pkg/connection/reconcile_sink.go @@ -0,0 +1,154 @@ +// Copyright 2022 StreamNative +// +// 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 connection + +import ( + "context" + "errors" + "fmt" + + "github.com/go-logr/logr" + resourcev1alpha1 "github.com/streamnative/pulsar-resources-operator/api/v1alpha1" + "github.com/streamnative/pulsar-resources-operator/pkg/admin" + "github.com/streamnative/pulsar-resources-operator/pkg/feature" + "github.com/streamnative/pulsar-resources-operator/pkg/reconciler" + "k8s.io/apimachinery/pkg/api/meta" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +// PulsarSinkReconciler reconciles a PulsarSink object +type PulsarSinkReconciler struct { + conn *PulsarConnectionReconciler + log logr.Logger +} + +func makeSinksReconciler(r *PulsarConnectionReconciler) reconciler.Interface { + return &PulsarSinkReconciler{ + conn: r, + log: makeSubResourceLog(r, "PulsarSink"), + } +} + +// Observe checks the updates of object +func (r *PulsarSinkReconciler) Observe(ctx context.Context) error { + r.log.V(1).Info("Start Observe") + + sinksList := &resourcev1alpha1.PulsarSinkList{} + if err := r.conn.client.List(ctx, sinksList, client.InNamespace(r.conn.connection.Namespace), + client.MatchingFields(map[string]string{ + ".spec.connectionRef.name": r.conn.connection.Name, + })); err != nil { + return fmt.Errorf("list sinks [%w]", err) + } + r.log.V(1).Info("Observed sinks items", "Count", len(sinksList.Items)) + + r.conn.sinks = sinksList.Items + for i := range r.conn.sinks { + if !resourcev1alpha1.IsPulsarResourceReady(&r.conn.sinks[i]) { + r.conn.addUnreadyResource(&r.conn.sinks[i]) + } + } + + r.log.V(1).Info("Observe Done") + return nil +} + +// Reconcile reconciles the object +func (r *PulsarSinkReconciler) Reconcile(ctx context.Context) error { + r.log.V(1).Info("Start Reconcile") + + for i := range r.conn.sinks { + sink := &r.conn.sinks[i] + if err := r.ReconcileSink(ctx, r.conn.pulsarAdminV3, sink); err != nil { + return fmt.Errorf("reconcile sink [%s] [%w]", sink.Name, err) + } + } + + return nil +} + +// ReconcileSink reconciles the sink +func (r *PulsarSinkReconciler) ReconcileSink(ctx context.Context, pulsarAdmin admin.PulsarAdmin, sink *resourcev1alpha1.PulsarSink) error { + log := r.log.WithValues("name", sink.Name, "namespace", sink.Namespace) + log.Info("Start Reconcile") + + if !sink.DeletionTimestamp.IsZero() { + log.Info("Deleting sink", "LifecyclePolicy", sink.Spec.LifecyclePolicy) + + if sink.Spec.LifecyclePolicy != resourcev1alpha1.KeepAfterDeletion { + if err := pulsarAdmin.DeletePulsarSink(sink.Spec.Tenant, sink.Spec.Namespace, sink.Spec.Name); err != nil && !admin.IsNotFound(err) { + log.Error(err, "Failed to delete sink") + return err + } + } + + // TODO use otelcontroller until kube-instrumentation upgrade controller-runtime version to newer + controllerutil.RemoveFinalizer(sink, resourcev1alpha1.FinalizerName) + if err := r.conn.client.Update(ctx, sink); err != nil { + log.Error(err, "Failed to remove finalizer") + return err + } + return nil + } + + if sink.Spec.LifecyclePolicy != resourcev1alpha1.KeepAfterDeletion { + // TODO use otelcontroller until kube-instrumentation upgrade controller-runtime version to newer + controllerutil.AddFinalizer(sink, resourcev1alpha1.FinalizerName) + if err := r.conn.client.Update(ctx, sink); err != nil { + log.Error(err, "Failed to add finalizer") + return err + } + } + + if resourcev1alpha1.IsPulsarResourceReady(sink) && + !feature.DefaultFeatureGate.Enabled(feature.AlwaysUpdatePulsarResource) { + log.Info("Skip reconcile, function resource is ready") + return nil + } + + if sink.Spec.Archive == nil && sink.Spec.SinkType == "" { + err := errors.New("no package URL or sink type provided") + return err + } + + packageURL := "" + + if sink.Spec.Archive.URL != "" { + packageURL = validateURL(sink.Spec.Archive.URL) + if packageURL == "" { + err := errors.New("invalid package URL") + return err + } + } + + if err := pulsarAdmin.ApplyPulsarSink(sink.Spec.Tenant, sink.Spec.Namespace, sink.Spec.Name, packageURL, &sink.Spec, sink.Status.ObservedGeneration > 1); err != nil { + meta.SetStatusCondition(&sink.Status.Conditions, *NewErrorCondition(sink.Generation, err.Error())) + log.Error(err, "Failed to apply sink") + if err := r.conn.client.Status().Update(ctx, sink); err != nil { + log.Error(err, "Failed to update the sink status") + return nil + } + return err + } + + sink.Status.ObservedGeneration = sink.Generation + meta.SetStatusCondition(&sink.Status.Conditions, *NewReadyCondition(sink.Generation)) + if err := r.conn.client.Status().Update(ctx, sink); err != nil { + log.Error(err, "Failed to update the sink status") + return err + } + return nil +} diff --git a/pkg/connection/reconcile_source.go b/pkg/connection/reconcile_source.go new file mode 100644 index 00000000..08c0b7a0 --- /dev/null +++ b/pkg/connection/reconcile_source.go @@ -0,0 +1,153 @@ +// Copyright 2022 StreamNative +// +// 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 connection + +import ( + "context" + "errors" + "fmt" + + "github.com/go-logr/logr" + resourcev1alpha1 "github.com/streamnative/pulsar-resources-operator/api/v1alpha1" + "github.com/streamnative/pulsar-resources-operator/pkg/admin" + "github.com/streamnative/pulsar-resources-operator/pkg/feature" + "github.com/streamnative/pulsar-resources-operator/pkg/reconciler" + "k8s.io/apimachinery/pkg/api/meta" + "sigs.k8s.io/controller-runtime/pkg/client" + "sigs.k8s.io/controller-runtime/pkg/controller/controllerutil" +) + +// PulsarSourceReconciler reconciles a PulsarSource object +type PulsarSourceReconciler struct { + conn *PulsarConnectionReconciler + log logr.Logger +} + +func makeSourcesReconciler(r *PulsarConnectionReconciler) reconciler.Interface { + return &PulsarSourceReconciler{ + conn: r, + log: makeSubResourceLog(r, "PulsarSource"), + } +} + +// Observe checks the updates of object +func (r *PulsarSourceReconciler) Observe(ctx context.Context) error { + r.log.V(1).Info("Start Observe") + + sourcesList := &resourcev1alpha1.PulsarSourceList{} + if err := r.conn.client.List(ctx, sourcesList, client.InNamespace(r.conn.connection.Namespace), + client.MatchingFields(map[string]string{ + ".spec.connectionRef.name": r.conn.connection.Name, + })); err != nil { + return fmt.Errorf("list sources [%w]", err) + } + r.log.V(1).Info("Observed sources items", "Count", len(sourcesList.Items)) + + r.conn.sources = sourcesList.Items + r.log.Info("Observe sources", "Count", len(r.conn.sources)) + for i := range r.conn.sources { + if !resourcev1alpha1.IsPulsarResourceReady(&r.conn.sources[i]) { + r.conn.addUnreadyResource(&r.conn.sources[i]) + } + } + + r.log.V(1).Info("Observe Done") + return nil +} + +// Reconcile reconciles the object +func (r *PulsarSourceReconciler) Reconcile(ctx context.Context) error { + r.log.V(1).Info("Start Reconcile") + + for i := range r.conn.sources { + source := &r.conn.sources[i] + r.log.Info("Reconcile source", "Name", source.Name) + if err := r.ReconcileSource(ctx, r.conn.pulsarAdminV3, source); err != nil { + return fmt.Errorf("reconcile source [%s] [%w]", source.Name, err) + } + } + + return nil +} + +// ReconcileSource reconciles the source +func (r *PulsarSourceReconciler) ReconcileSource(ctx context.Context, pulsarAdmin admin.PulsarAdmin, source *resourcev1alpha1.PulsarSource) error { + log := r.log.WithValues("name", source.Name, "namespace", source.Namespace) + log.Info("Start Reconcile") + + if !source.DeletionTimestamp.IsZero() { + log.Info("Deleting source", "LifecyclePolicy", source.Spec.LifecyclePolicy) + + if source.Spec.LifecyclePolicy != resourcev1alpha1.KeepAfterDeletion { + if err := pulsarAdmin.DeletePulsarSource(source.Spec.Tenant, source.Spec.Namespace, source.Spec.Name); err != nil && !admin.IsNotFound(err) { + log.Error(err, "Failed to delete source") + return err + } + } + + // TODO use otelcontroller until kube-instrumentation upgrade controller-runtime version to newer + controllerutil.RemoveFinalizer(source, resourcev1alpha1.FinalizerName) + if err := r.conn.client.Update(ctx, source); err != nil { + log.Error(err, "Failed to remove finalizer") + return err + } + return nil + } + + if source.Spec.LifecyclePolicy != resourcev1alpha1.KeepAfterDeletion { + // TODO use otelcontroller until kube-instrumentation upgrade controller-runtime version to newer + controllerutil.AddFinalizer(source, resourcev1alpha1.FinalizerName) + if err := r.conn.client.Update(ctx, source); err != nil { + log.Error(err, "Failed to add finalizer") + return err + } + } + + if resourcev1alpha1.IsPulsarResourceReady(source) && + !feature.DefaultFeatureGate.Enabled(feature.AlwaysUpdatePulsarResource) { + log.Info("Skip reconcile, function resource is ready") + return nil + } + + if source.Spec.Archive == nil { + err := errors.New("invalid package URL") + return err + } + + packageURL := validateURL(source.Spec.Archive.URL) + + if packageURL == "" { + err := errors.New("invalid package URL") + return err + } + + if err := pulsarAdmin.ApplyPulsarSource(source.Spec.Tenant, source.Spec.Namespace, source.Spec.Name, packageURL, &source.Spec, source.Status.ObservedGeneration > 1); err != nil { + meta.SetStatusCondition(&source.Status.Conditions, *NewErrorCondition(source.Generation, err.Error())) + log.Error(err, "Failed to apply source") + if err := r.conn.client.Status().Update(ctx, source); err != nil { + log.Error(err, "Failed to update the source status") + return nil + } + return err + } + + source.Status.ObservedGeneration = source.Generation + meta.SetStatusCondition(&source.Status.Conditions, *NewReadyCondition(source.Generation)) + if err := r.conn.client.Status().Update(ctx, source); err != nil { + log.Error(err, "Failed to update the source status") + return err + } + return nil +} diff --git a/pkg/connection/reconciler.go b/pkg/connection/reconciler.go index 660927c7..75493dda 100644 --- a/pkg/connection/reconciler.go +++ b/pkg/connection/reconciler.go @@ -18,6 +18,8 @@ import ( "context" "fmt" + "github.com/apache/pulsar-client-go/pulsaradmin/pkg/admin/config" + "github.com/go-logr/logr" "github.com/streamnative/pulsar-resources-operator/pkg/utils" corev1 "k8s.io/api/core/v1" @@ -44,10 +46,15 @@ type PulsarConnectionReconciler struct { topics []resourcev1alpha1.PulsarTopic permissions []resourcev1alpha1.PulsarPermission geoReplications []resourcev1alpha1.PulsarGeoReplication + packages []resourcev1alpha1.PulsarPackage + sinks []resourcev1alpha1.PulsarSink + sources []resourcev1alpha1.PulsarSource + functions []resourcev1alpha1.PulsarFunction unreadyResources []string - pulsarAdmin admin.PulsarAdmin - reconcilers []reconciler.Interface + pulsarAdmin admin.PulsarAdmin + pulsarAdminV3 admin.PulsarAdmin + reconcilers []reconciler.Interface } var _ reconciler.Interface = &PulsarConnectionReconciler{} @@ -67,6 +74,10 @@ func MakeReconciler(log logr.Logger, k8sClient client.Client, creator admin.Puls makeNamespacesReconciler(r), makeTopicsReconciler(r), makePermissionsReconciler(r), + makeFunctionsReconciler(r), + makeSinksReconciler(r), + makeSourcesReconciler(r), + makePackagesReconciler(r), } return r } @@ -78,6 +89,7 @@ func makeSubResourceLog(r *PulsarConnectionReconciler, name string) logr.Logger // Observe checks the updates of object func (r *PulsarConnectionReconciler) Observe(ctx context.Context) error { + r.log.Info("Start PulsarConnectionReconciler Observe") for _, reconciler := range r.reconcilers { if err := reconciler.Observe(ctx); err != nil { return err @@ -145,6 +157,22 @@ func (r *PulsarConnectionReconciler) Reconcile(ctx context.Context) error { r.pulsarAdmin = nil }() + pulsarConfig, err = r.MakePulsarAdminConfigWithAPIVersion(ctx, config.V3) + if err != nil { + return err + } + r.pulsarAdminV3, err = r.creator(*pulsarConfig) + if err != nil { + log.Error(err, "create pulsar admin v3") + return err + } + defer func() { + if err := r.pulsarAdminV3.Close(); err != nil { + log.Error(err, "close pulsar admin v3") + } + r.pulsarAdminV3 = nil + }() + if r.connection.DeletionTimestamp.IsZero() { for _, reconciler := range r.reconcilers { if err = reconciler.Reconcile(ctx); err != nil { @@ -234,6 +262,16 @@ func (r *PulsarConnectionReconciler) MakePulsarAdminConfig(ctx context.Context) return MakePulsarAdminConfig(ctx, r.connection, r.client) } +// MakePulsarAdminConfigWithAPIVersion create pulsar admin configuration with api version +func (r *PulsarConnectionReconciler) MakePulsarAdminConfigWithAPIVersion(ctx context.Context, ver config.APIVersion) (*admin.PulsarAdminConfig, error) { + c, e := MakePulsarAdminConfig(ctx, r.connection, r.client) + if e != nil { + return nil, e + } + c.PulsarAPIVersion = &ver + return c, nil +} + // MakePulsarAdminConfig create pulsar admin configuration func MakePulsarAdminConfig(ctx context.Context, connection *resourcev1alpha1.PulsarConnection, k8sClient client.Client) (*admin.PulsarAdminConfig, error) { diff --git a/pkg/utils/common.go b/pkg/utils/common.go new file mode 100644 index 00000000..c46de51d --- /dev/null +++ b/pkg/utils/common.go @@ -0,0 +1,48 @@ +// Copyright 2023 StreamNative +// +// 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 utils + +import ( + "encoding/json" + + apiextensionsv1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" +) + +// ConvertMap converts a map[string]string to a map[string]interface{} +func ConvertMap(input map[string]string) map[string]interface{} { + // Create an empty map[string]interface{} + result := make(map[string]interface{}) + + // Loop through each key-value pair in the input map + for key, value := range input { + // Assign the value to the result map with the same key + result[key] = value + } + + return result +} + +// ConvertJSONToMapStringInterface converts a JSON object to a map[string]interface{} +func ConvertJSONToMapStringInterface(raw *apiextensionsv1.JSON) (map[string]interface{}, error) { + // Create an empty map[string]interface{} + result := make(map[string]interface{}) + + // Unmarshal the raw JSON object into the result map + if err := json.Unmarshal(raw.Raw, &result); err != nil { + return nil, err + } + + return result, nil +} diff --git a/tests/go.mod b/tests/go.mod index a4e3c8cb..186d59ee 100644 --- a/tests/go.mod +++ b/tests/go.mod @@ -20,6 +20,8 @@ require ( require k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b +require k8s.io/apiextensions-apiserver v0.23.0 + require ( cloud.google.com/go v0.81.0 // indirect github.com/99designs/go-keychain v0.0.0-20191008050251-8e49817e8af4 // indirect diff --git a/tests/go.sum b/tests/go.sum index e4be16b4..44197a42 100644 --- a/tests/go.sum +++ b/tests/go.sum @@ -58,6 +58,7 @@ github.com/BurntSushi/xgb v0.0.0-20160522181843-27f122750802/go.mod h1:IVnqGOEym github.com/DataDog/zstd v1.5.0 h1:+K/VEwIAaPcHiMtQvpLD4lqW7f0Gk3xdYZmI1hD+CXo= github.com/DataDog/zstd v1.5.0/go.mod h1:g4AWEaM3yOg3HYfnJ3YIawPnVdXJh9QME85blwSAmyw= github.com/NYTimes/gziphandler v0.0.0-20170623195520-56545f4a5d46/go.mod h1:3wb06e3pkSAbeQ52E9H9iFoQsEEwGN64994WTCIhntQ= +github.com/NYTimes/gziphandler v1.1.1/go.mod h1:n/CVRwUEOgIxrgPvAQhUUr9oeUtvrhMomdKFjzJNB0c= github.com/OneOfOne/xxhash v1.2.2/go.mod h1:HSdplMjZKSmBqAxg5vPj2TmRDmfkzw+cTzAElWljhcU= github.com/PuerkitoBio/purell v1.1.1/go.mod h1:c11w/QuzBsJSee3cPx9rAFu61PvFxuPbtSwDGJws/X0= github.com/PuerkitoBio/urlesc v0.0.0-20170810143723-de5bf2ad4578/go.mod h1:uGdkoq3SwY9Y+13GIhn11/XLaGBb4BfwItxLd5jeuXE= @@ -67,6 +68,7 @@ github.com/alecthomas/units v0.0.0-20151022065526-2efee857e7cf/go.mod h1:ybxpYRF github.com/alecthomas/units v0.0.0-20190717042225-c3de453c63f4/go.mod h1:ybxpYRFXyAe+OPACYpWeL0wqObRcbAqCMya13uyzqw0= github.com/alecthomas/units v0.0.0-20190924025748-f65c72e2690d/go.mod h1:rBZYJk541a8SKzHPHnH3zbiI+7dagKZ0cgpgrD7Fyho= github.com/antihax/optional v1.0.0/go.mod h1:uupD/76wgC+ih3iEmQUL+0Ugr19nfwCT1kdvxnR2qWY= +github.com/antlr/antlr4/runtime/Go/antlr v0.0.0-20210826220005-b48c857c3a0e/go.mod h1:F7bn7fEU90QkQ3tnmaTx3LTKLEDqnwWODIYppRQ5hnY= github.com/apache/pulsar-client-go v0.12.1 h1:jRA+VQKebVA4iIvojKUlkCeJ/R7oOxr/NXvwj+tNLkk= github.com/apache/pulsar-client-go v0.12.1/go.mod h1:dkutuH4oS2pXiGm+Ti7fQZ4MRjrMPZ8IJeEGAWMeckk= github.com/ardielle/ardielle-go v1.5.2 h1:TilHTpHIQJ27R1Tl/iITBzMwiUGSlVfiVhwDNGM3Zj4= @@ -86,9 +88,12 @@ github.com/beorn7/perks v1.0.1/go.mod h1:G2ZrVWU2WbWT9wwq4/hrbKbnv/1ERSJQ0ibhJ6r github.com/bgentry/speakeasy v0.1.0/go.mod h1:+zsyZBPWlz7T6j88CTgSN5bM796AkVf0kBD4zp0CCIs= github.com/bits-and-blooms/bitset v1.4.0 h1:+YZ8ePm+He2pU3dZlIZiOeAKfrBkXi1lSrXJ/Xzgbu8= github.com/bits-and-blooms/bitset v1.4.0/go.mod h1:gIdJ4wp64HaoK2YrL1Q5/N7Y16edYb8uY+O0FJTyyDA= +github.com/bketelsen/crypt v0.0.3-0.20200106085610-5cbc8cc4026c/go.mod h1:MKsuJmJgSg28kpZDP6UIiPt0e0Oz0kqKNGyRaWEPv84= github.com/bketelsen/crypt v0.0.4/go.mod h1:aI6NrJ0pMGgvZKL1iVgXLnfIFJtfV+bKCoqOes/6LfM= github.com/blang/semver v3.5.1+incompatible/go.mod h1:kRBLl5iJ+tD4TcOOxsy/0fnwebNt5EWlYSAyrTnjyyk= github.com/census-instrumentation/opencensus-proto v0.2.1/go.mod h1:f6KPmirojxKA12rnyqOA5BBL4O983OfeGPqjHWSTneU= +github.com/certifi/gocertifi v0.0.0-20191021191039-0944d244cd40/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= +github.com/certifi/gocertifi v0.0.0-20200922220541-2c3bb06c6054/go.mod h1:sGbDF6GwGcLpkNXPUTkMRoywsNa/ol15pxFe6ERfguA= github.com/cespare/xxhash v1.1.0/go.mod h1:XrSqR1VqqWfGrhpAt58auRo0WTKS1nRRg3ghfAqPWnc= github.com/cespare/xxhash/v2 v2.1.1/go.mod h1:VGX0DQ3Q6kWi7AoAeZDth3/j3BFtOZR5XLFGgcrjCOs= github.com/cespare/xxhash/v2 v2.2.0 h1:DC2CZ1Ep5Y4k3ZQ899DldepgrayRUGE6BBZ/cd9Cj44= @@ -101,8 +106,16 @@ github.com/cncf/udpa/go v0.0.0-20191209042840-269d4d468f6f/go.mod h1:M8M6+tZqaGX github.com/cncf/udpa/go v0.0.0-20200629203442-efcf912fb354/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/udpa/go v0.0.0-20201120205902-5459f2c99403/go.mod h1:WmhPx2Nbnhtbo57+VJT5O0JRkEi1Wbu0z5j0R8u5Hbk= github.com/cncf/xds/go v0.0.0-20210312221358-fbca930ec8ed/go.mod h1:eXthEFrGJvWHgFFCl3hGmgk+/aYT6PnTQLykKQRLhEs= +github.com/cockroachdb/datadriven v0.0.0-20200714090401-bf6692d28da5/go.mod h1:h6jFvWxBdQXxjopDMZyH2UVceIRfR84bdzbkoKrsWNo= +github.com/cockroachdb/errors v1.2.4/go.mod h1:rQD95gz6FARkaKkQXUksEje/d9a6wBJoCr5oaCLELYA= +github.com/cockroachdb/logtags v0.0.0-20190617123548-eb05cc24525f/go.mod h1:i/u985jwjWRlyHXQbwatDASoW0RMlZ/3i9yJHE2xLkI= +github.com/coreos/bbolt v1.3.2/go.mod h1:iRUV2dpdMOn7Bo10OQBFzIJO9kkE559Wcmn+qkEiiKk= +github.com/coreos/etcd v3.3.13+incompatible/go.mod h1:uF7uidLiAD3TWHmW31ZFd/JWoc32PjwdhPthX9715RE= +github.com/coreos/go-oidc v2.1.0+incompatible/go.mod h1:CgnwVTmzoESiwO9qyAFEMiHoZ1nMCKZlZ9V6mm3/LKc= github.com/coreos/go-semver v0.3.0/go.mod h1:nnelYz7RCh+5ahJtPPxZlU+153eP4D4r3EedlOD2RNk= +github.com/coreos/go-systemd v0.0.0-20190321100706-95778dfbb74e/go.mod h1:F5haX7vjVVG0kc13fIWeqUViNPyEJxv/OmvnBo0Yme4= github.com/coreos/go-systemd/v22 v22.3.2/go.mod h1:Y58oyj3AT4RCenI/lSvhwexgC+NSVTIJ3seZv2GcEnc= +github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfcXa63jLwjI0eiQQMgzzUDFVpN/nH/eA= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/creack/pty v1.1.9/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= github.com/creack/pty v1.1.11/go.mod h1:oKZEueFk5CKHvIhNR5MUki03XCEU+Q6VDXinZuGJ33E= @@ -111,14 +124,18 @@ github.com/danieljoos/wincred v1.1.2/go.mod h1:GijpziifJoIBfYh+S7BbkdUTU4LfM+QnG github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= +github.com/dgrijalva/jwt-go v3.2.0+incompatible/go.mod h1:E3ru+11k8xSBh+hMPgOLZmtrrCbhqsmaPHjLKYnJCaQ= +github.com/dgryski/go-sip13 v0.0.0-20181026042036-e10d5fee7954/go.mod h1:vAd38F8PWV+bWy6jNmig1y/TA+kYO4g3RSRF0IAv0no= github.com/dimfeld/httptreemux v5.0.1+incompatible h1:Qj3gVcDNoOthBAqftuD596rm4wg/adLLz5xh5CmpiCA= github.com/dimfeld/httptreemux v5.0.1+incompatible/go.mod h1:rbUlSV+CCpv/SuqUTP/8Bk2O3LyUV436/yaRGkhP6Z0= github.com/docopt/docopt-go v0.0.0-20180111231733-ee0de3bc6815/go.mod h1:WwZ+bS3ebgob9U8Nd0kOddGdZWjyMGR8Wziv+TBNwSE= +github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk= github.com/dvsekhvalnov/jose2go v1.6.0 h1:Y9gnSnP4qEI0+/uQkHvFXeD2PLPJeXEL+ySMEA2EjTY= github.com/dvsekhvalnov/jose2go v1.6.0/go.mod h1:QsHjhyTlD/lAVqn/NSbVZmSCGeDehTB/mPZadG+mhXU= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153 h1:yUdfgN0XgIJw7foRItutHYUIhlcKzcSf5vDpdhQAKTc= github.com/elazarl/goproxy v0.0.0-20180725130230-947c36da3153/go.mod h1:/Zj4wYkgs4iZTTu3o/KG3Itv/qCCa8VVMlb3i9OVuzc= github.com/emicklei/go-restful v0.0.0-20170410110728-ff4f55a20633/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= +github.com/emicklei/go-restful v2.9.5+incompatible/go.mod h1:otzb+WCGbkyDHkqmQmT5YD2WR4BBwUdeQoFo8l/7tVs= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -139,6 +156,7 @@ github.com/fsnotify/fsnotify v1.4.9/go.mod h1:znqG4EE+3YCdAaPaxE2ZRY/06pZUdp0tY4 github.com/fsnotify/fsnotify v1.5.1 h1:mZcQUHVQUQWoPXXtuf9yuEXKudkV2sx1E06UadKWpgI= github.com/fsnotify/fsnotify v1.5.1/go.mod h1:T3375wBYaZdLLcVNkcVbzGHY7f1l/uK5T5Ai1i3InKU= github.com/getkin/kin-openapi v0.76.0/go.mod h1:660oXbgy5JFMKreazJaQTw7o+X00qeSyhcnluiMv+Xg= +github.com/getsentry/raven-go v0.2.0/go.mod h1:KungGk8q33+aIAZUIVWZDr2OfAEBsO49PX4NzFV5kcQ= github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04= github.com/go-gl/glfw v0.0.0-20190409004039-e6da0acd62b1/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU= github.com/go-gl/glfw/v3.3/glfw v0.0.0-20191125211704-12ad95a8df72/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8= @@ -160,7 +178,9 @@ github.com/go-logr/zapr v1.2.0/go.mod h1:Qa4Bsj2Vb+FAVeAKsLD8RLQ+YRJB8YDmOAKxaBQ github.com/go-openapi/jsonpointer v0.19.3/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonpointer v0.19.5/go.mod h1:Pl9vOtqEWErmShwVjC8pYs9cog34VGT37dQOVbmoatg= github.com/go-openapi/jsonreference v0.19.3/go.mod h1:rjx6GuL8TTa9VaixXglHmQmIL98+wF9xc8zWvFonSJ8= +github.com/go-openapi/jsonreference v0.19.5/go.mod h1:RdybgQwPxbL4UEjuAruzK1x3nE69AqPYEJeo/TWfEeg= github.com/go-openapi/swag v0.19.5/go.mod h1:POnQmlKehdgb5mhVOsnJFsivZCEZ/vjK9gh66Z9tfKk= +github.com/go-openapi/swag v0.19.14/go.mod h1:QYRuS/SOXUCsnplDa677K7+DxSOj6IPNl/eQntq43wQ= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg= github.com/go-stack/stack v1.8.0/go.mod h1:v0f6uXyyMGvRgIKkXu+yp6POWl0qKG85gN/melR3HDY= github.com/go-task/slim-sprig v0.0.0-20210107165309-348f09dbbbc0/go.mod h1:fyg7847qk6SyHyPtNmDHnmrv/HOrqktSC+C9fM+CJOE= @@ -168,12 +188,16 @@ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2 h1:ZpnhV/YsD2/4cESfV5+ github.com/godbus/dbus v0.0.0-20190726142602-4481cbc300e2/go.mod h1:bBOAhwG1umN6/6ZUMtDFBMQR8jRg9O75tm9K00oMsK4= github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA= github.com/gogo/protobuf v1.1.1/go.mod h1:r8qH/GZQm5c6nD/R0oafs1akxWv10x8SbQlK7atdtwQ= +github.com/gogo/protobuf v1.2.1/go.mod h1:hp+jE20tsWTFYpLwKvXlhS1hjn+gTNwPg2I6zVXpSg4= +github.com/gogo/protobuf v1.3.1/go.mod h1:SlYgWuQ5SjCEi6WLHjHCa1yvBfUnHcTbrrZtXPKa29o= github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q= github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q= github.com/golang-jwt/jwt v3.2.1+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang-jwt/jwt v3.2.2+incompatible h1:IfV12K8xAKAnZqdXVzCZ+TOjboZ2keLg81eXfW3O+oY= github.com/golang-jwt/jwt v3.2.2+incompatible/go.mod h1:8pz2t5EyA70fFQQSrl6XZXzqecmYZeUEB8OUGHkxJ+I= github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q= +github.com/golang/glog v1.0.0/go.mod h1:EWib/APOK0SL3dFbYqvxE3UYd8E6s1ouQ7iEp/0LWV4= +github.com/golang/groupcache v0.0.0-20190129154638-5b532d6fd5ef/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20191227052852-215e87163ea7/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= github.com/golang/groupcache v0.0.0-20200121045136-8c9f03a8e57e/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc= @@ -210,6 +234,8 @@ github.com/golang/snappy v0.0.1/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEW github.com/google/btree v0.0.0-20180813153112-4030bb1f1f0c/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.0/go.mod h1:lNA+9X1NB3Zf8V7Ke586lFgjr2dZNuvo3lPJSGZ5JPQ= github.com/google/btree v1.0.1/go.mod h1:xXMiIv4Fb/0kKde4SpL7qlzvu5cMJDRkFDxJfI9uaxA= +github.com/google/cel-go v0.9.0/go.mod h1:U7ayypeSkw23szu4GaQTPJGx66c20mx8JklMSxrmI1w= +github.com/google/cel-spec v0.6.0/go.mod h1:Nwjgxy5CbjlPrtCWjeDjUyKMl8w41YBYGjsyDdqk0xA= github.com/google/go-cmp v0.2.0/go.mod h1:oXzfMopK8JAjlY9xF4vHSVASa0yLyX7SntLO5aqRK0M= github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= github.com/google/go-cmp v0.3.1/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU= @@ -256,6 +282,10 @@ github.com/gorilla/mux v1.7.4/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB7 github.com/gorilla/mux v1.8.0/go.mod h1:DVbg23sWSpFRCP0SfiEN6jmj59UnW/n46BH5rLB71So= github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/gregjones/httpcache v0.0.0-20180305231024-9cad4c3443a7/go.mod h1:FecbI9+v66THATjSRHfNgh1IVFe/9kFxbXtjV0ctIMA= +github.com/grpc-ecosystem/go-grpc-middleware v1.0.0/go.mod h1:FiyG127CGDf3tlThmgyCl78X/SZQqEOJBCDaAfeWzPs= +github.com/grpc-ecosystem/go-grpc-middleware v1.3.0/go.mod h1:z0ButlSOZa5vEBq9m2m2hlwIgKw+rp3sdCBRoJY+30Y= +github.com/grpc-ecosystem/go-grpc-prometheus v1.2.0/go.mod h1:8NvIoxWQoOIhqOTXgfV/d3M/q6VIi02HzZEHgUlZvzk= +github.com/grpc-ecosystem/grpc-gateway v1.9.0/go.mod h1:vNeuVxBJEsws4ogUvrchl83t/GYV9WGTSLVdBhOQFDY= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c h1:6rhixN/i8ZofjG1Y75iExal34USq5p+wiN1tpie8IrU= github.com/gsterjov/go-libsecret v0.0.0-20161001094733-a6f4afe4910c/go.mod h1:NMPJylDgVpX0MLRlPy15sqSwOFv/U1GZ2m21JhFfek0= @@ -292,6 +322,9 @@ github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANyt github.com/jawher/mow.cli v1.0.4/go.mod h1:5hQj2V8g+qYmLUVWqu4Wuja1pI57M83EChYLVZ0sMKk= github.com/jawher/mow.cli v1.2.0/go.mod h1:y+pcA3jBAdo/GIZx/0rFjw/K2bVEODP9rfZOfaiq8Ko= github.com/jmespath/go-jmespath v0.3.0/go.mod h1:9QtRXoHjLGCJ5IBSaohpXITPlowMeeYCZ7fLUTSywik= +github.com/jonboulle/clockwork v0.1.0/go.mod h1:Ii8DK3G1RaLaWxj9trq07+26W01tbo22gdxWY5EU2bo= +github.com/jonboulle/clockwork v0.2.2/go.mod h1:Pkfl5aHPm1nk2H9h0bjmnJD/BcgbGXUBGnn1kMkgxc8= +github.com/josharian/intern v1.0.0/go.mod h1:5DoeVV0s6jJacbCEi61lwdGj/aVlrQvzHFFd8Hwg//Y= github.com/jpillora/backoff v1.0.0/go.mod h1:J/6gKK9jxlEcS3zixgDgUAsiuZ7yrSoa/FX5e0EB2j4= github.com/json-iterator/go v1.1.6/go.mod h1:+SdeFBvtyEkXs7REEP0seUULqWtbJapLOCVDaaPEHmU= github.com/json-iterator/go v1.1.10/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4= @@ -303,6 +336,8 @@ github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/X github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU= github.com/julienschmidt/httprouter v1.2.0/go.mod h1:SYymIcj16QtmaHHD7aYtjjsJG7VTCxuUUipMqKk8s4w= github.com/julienschmidt/httprouter v1.3.0/go.mod h1:JR6WtHb+2LUe8TCKY3cZOxFyyO8IZAc4RVcycCCAKdM= +github.com/kisielk/errcheck v1.1.0/go.mod h1:EZBBE59ingxPouuu3KfxchcWSUPOHkagtvWXihfKN4Q= +github.com/kisielk/errcheck v1.2.0/go.mod h1:/BMXB+zMLi60iA8Vv6Ksmxu/1UDYcXs4uQLJ+jE2L00= github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8= github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck= github.com/klauspost/compress v1.14.4 h1:eijASRJcobkVtSt81Olfh7JX43osYLwy5krOJo6YEu4= @@ -321,9 +356,11 @@ github.com/kr/text v0.2.0 h1:5Nx0Ya0ZqY2ygV366QzturHI13Jq95ApcVaJBhpS+AY= github.com/kr/text v0.2.0/go.mod h1:eLer722TekiGuMkidMxC/pM04lWEeraHUUmBw8l2grE= github.com/linkedin/goavro/v2 v2.9.8 h1:jN50elxBsGBDGVDEKqUlDuU1cFwJ11K/yrJCBMe/7Wg= github.com/linkedin/goavro/v2 v2.9.8/go.mod h1:UgQUb2N/pmueQYH9bfqFioWxzYCZXSfF8Jw03O5sjqA= +github.com/magiconair/properties v1.8.1/go.mod h1:PppfXfuXeibc/6YijjN8zIbojt8czPbwD3XqdrwzmxQ= github.com/magiconair/properties v1.8.5/go.mod h1:y3VJvCyxH9uVvJTWEGAELF3aiYNyPKd5NZ3oSwXrF60= github.com/mailru/easyjson v0.0.0-20190614124828-94de47d64c63/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= github.com/mailru/easyjson v0.0.0-20190626092158-b2ccc519800e/go.mod h1:C1wdFJiN94OJF2b5HbByQZoLdCWB1Yqtg26g4irojpc= +github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNxMWT7Zi4= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -333,6 +370,7 @@ github.com/matttproud/golang_protobuf_extensions/v2 v2.0.0/go.mod h1:QUyp042oQth github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg= github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc= github.com/mitchellh/go-homedir v1.0.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= +github.com/mitchellh/go-homedir v1.1.0/go.mod h1:SfyaCUpYCn1Vlf4IUYiD9fPX4A5wJrkLzIz1N1q0pr0= github.com/mitchellh/go-testing-interface v1.0.0/go.mod h1:kRemZodwjscx+RGhAo8eIhFbs2+BFgRtFPeD/KE+zxI= github.com/mitchellh/gox v0.4.0/go.mod h1:Sd9lOJ0+aimLBi73mGofS1ycjY8lL3uZM3JPS42BGNg= github.com/mitchellh/iochan v1.0.0/go.mod h1:JwYml1nuB7xOzsp52dPpHFffvOCDupsG0QubkSMEySY= @@ -352,6 +390,7 @@ github.com/modern-go/reflect2 v1.0.2/go.mod h1:yWuevngMOJpCy52FWWMvUC8ws7m/LJsjY github.com/mtibben/percent v0.2.1 h1:5gssi8Nqo8QU/r2pynCm+hBQHpkB/uNK7BJCFogWdzs= github.com/mtibben/percent v0.2.1/go.mod h1:KG9uO+SZkUp+VkRHsCdYQV3XSZrrSpR3O9ibNBTZrns= github.com/munnerz/goautoneg v0.0.0-20120707110453-a547fc61f48d/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= +github.com/munnerz/goautoneg v0.0.0-20191010083416-a7dc8b61c822/go.mod h1:+n7T8mK8HuQTcFwEeznm/DIxMOiR9yIdICNftLE1DvQ= github.com/mwitkow/go-conntrack v0.0.0-20161129095857-cc309e4a2223/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mwitkow/go-conntrack v0.0.0-20190716064945-2f068394615f/go.mod h1:qRWi+5nqEBWmkhHvq77mSJWrCKwh8bxhgT7d/eI7P4U= github.com/mxk/go-flowrate v0.0.0-20140419014527-cca7078d478f/go.mod h1:ZdcZmHo+o7JKHSa8/e818NopupXU1YMK5fe1lsApnBw= @@ -359,6 +398,7 @@ github.com/niemeyer/pretty v0.0.0-20200227124842-a10e7caefd8e/go.mod h1:zD1mROLA github.com/nxadm/tail v1.4.4/go.mod h1:kenIhsEOeOJmVchQTgglprH7qJGnHDVpk1VPCcaMI8A= github.com/nxadm/tail v1.4.8 h1:nPr65rt6Y5JFSKQO7qToXr7pePgD6Gwiw05lkbyAQTE= github.com/nxadm/tail v1.4.8/go.mod h1:+ncqLTQzXmGhMZNUePPaPqPvBxHAIsmXswZKocGu+AU= +github.com/oklog/ulid v1.3.1/go.mod h1:CirwcVhetQ6Lv90oh/F+FBtV6XMibvdAFo93nm5qn4U= github.com/onsi/ginkgo v0.0.0-20170829012221-11459a886d9c/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.6.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+WWjE= github.com/onsi/ginkgo v1.12.1/go.mod h1:zj2OWP4+oCPe1qIXoGWkgMRwljMUYCdkwsT2108oapk= @@ -374,7 +414,9 @@ github.com/onsi/gomega v1.10.1/go.mod h1:iN09h71vgCQne3DLsj+A5owkum+a2tYe+TOCB1y github.com/onsi/gomega v1.17.0/go.mod h1:HnhC7FXeEQY45zxNK3PPoIUhzk/80Xly9PcubAlGdZY= github.com/onsi/gomega v1.19.0 h1:4ieX6qQjPP/BfC3mpsAtIGGlxTWPeA3Inl/7DtXw1tw= github.com/onsi/gomega v1.19.0/go.mod h1:LY+I3pBVzYsTBU1AnDwOSxaYi9WoWiqgwooUqq9yPro= +github.com/opentracing/opentracing-go v1.1.0/go.mod h1:UkNAQd3GIcIGf0SeVgPpRdFStlNbqXla1AfSYxPUl2o= github.com/pascaldekloe/goe v0.0.0-20180627143212-57f6aae5913c/go.mod h1:lzWF7FIEvWOWxwDKqyGYQf6ZUaNfKdP144TG7ZOy1lc= +github.com/pelletier/go-toml v1.2.0/go.mod h1:5z9KED0ma1S8pY6P1sdut58dfprrGBbd/94hg7ilaic= github.com/pelletier/go-toml v1.9.3/go.mod h1:u1nR/EPcESfeI/szUZKdtJ0xRNbUoANCkoOuaOx1Y+c= github.com/peterbourgon/diskv v2.0.1+incompatible/go.mod h1:uqqh8zWWbv1HBMNONnaR/tNboyR3/BZd58JJSHlUSCU= github.com/pierrec/lz4 v2.0.5+incompatible h1:2xWsjqPFWcplujydGg4WmhC/6fZqK42wMM8aXeqhl0I= @@ -387,7 +429,9 @@ github.com/pkg/sftp v1.10.1/go.mod h1:lYOWFsE0bwd1+KfKJaKeuokY15vzFx25BLbzYYoAxZ github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM= github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4= github.com/posener/complete v1.1.1/go.mod h1:em0nMJCgc9GFtwrmVmEMR/ZL6WyhyjMBndrE9hABlRI= +github.com/pquerna/cachecontrol v0.0.0-20171018203845-0dec1b30a021/go.mod h1:prYjPmNq4d1NPVmpShWobRqXY3q7Vp+80DqgxxUrUIA= github.com/prometheus/client_golang v0.9.1/go.mod h1:7SWBe2y4D6OKWSNQJUaRYU/AaXPKyh/dDVn+NZz0KFw= +github.com/prometheus/client_golang v0.9.3/go.mod h1:/TN21ttK/J9q6uSwhBd54HahCDft0ttaMvbicHlPoso= github.com/prometheus/client_golang v1.0.0/go.mod h1:db9x61etRT2tGnBNRi70OPL5FsnadC4Ky3P0J6CfImo= github.com/prometheus/client_golang v1.7.1/go.mod h1:PY5Wy2awLA44sXw4AOSfFBetzPP4j5+D6mVACh+pe2M= github.com/prometheus/client_golang v1.11.0/go.mod h1:Z6t4BnS23TR94PD6BsDNk8yVqroYurpAkEiz0P2BEV0= @@ -399,6 +443,8 @@ github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1: github.com/prometheus/client_model v0.2.0/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA= github.com/prometheus/client_model v0.5.0 h1:VQw1hfvPvk3Uv6Qf29VrPF32JB6rtbgI6cYPYQjL0Qw= github.com/prometheus/client_model v0.5.0/go.mod h1:dTiFglRmd66nLR9Pv9f0mZi7B7fk5Pm3gvsjB5tr+kI= +github.com/prometheus/common v0.0.0-20181113130724-41aa239b4cce/go.mod h1:daVV7qP5qjZbuso7PdcryaAu0sAZbrN9i7WWcTMWvro= +github.com/prometheus/common v0.4.0/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.4.1/go.mod h1:TNfzLD0ON7rHzMJeJkieUDPYmFC7Snx/y86RQel1bk4= github.com/prometheus/common v0.10.0/go.mod h1:Tlit/dnDKsSWFlCLTWaA1cyBgKHSMdTB80sz/V91rCo= github.com/prometheus/common v0.26.0/go.mod h1:M7rCNAaPfAosfx8veZJCuw84e35h3Cfd9VFqTh1DIvc= @@ -406,11 +452,14 @@ github.com/prometheus/common v0.28.0/go.mod h1:vu+V0TpY+O6vW9J44gczi3Ap/oXXR10b+ github.com/prometheus/common v0.45.0 h1:2BGz0eBc2hdMDLnO/8n0jeB3oPrt2D08CekT0lneoxM= github.com/prometheus/common v0.45.0/go.mod h1:YJmSTw9BoKxJplESWWxlbyttQR4uaEcGyv9MZjVOJsY= github.com/prometheus/procfs v0.0.0-20181005140218-185b4288413d/go.mod h1:c3At6R/oaqEKCNdg8wHV1ftS6bRYblBhIjjI8uT2IGk= +github.com/prometheus/procfs v0.0.0-20190507164030-5867b95ac084/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.0.2/go.mod h1:TjEm7ze935MbeOT/UhFTIMYKhuLP4wbCsTZCD3I8kEA= github.com/prometheus/procfs v0.1.3/go.mod h1:lV6e/gmhEcM9IjHGsFOCxxuZ+z1YqCvr4OA4YeYWdaU= github.com/prometheus/procfs v0.6.0/go.mod h1:cz+aTbrPOrUb4q7XlbU9ygM+/jj0fzG6c1xBZuNvfVA= github.com/prometheus/procfs v0.12.0 h1:jluTpSng7V9hY0O2R9DzzJHYb2xULk9VTR1V1R/k6Bo= github.com/prometheus/procfs v0.12.0/go.mod h1:pcuDEFsWDnvcgNzo4EEweacyhjeA9Zk3cnaOZAZEfOo= +github.com/prometheus/tsdb v0.7.1/go.mod h1:qhTCs0VvXwvX/y3TZrWD7rabWM+ijKTux40TwIPHuXU= +github.com/rogpeppe/fastuuid v0.0.0-20150106093220-6724a57986af/go.mod h1:XWv6SoW27p1b0cqNHllgS5HIMJraePCO15w5zCzIWYg= github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ= github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4= github.com/rogpeppe/go-internal v1.10.0 h1:TMyTOH3F/DB16zRVcYyreMH6GnZZrwQVAoYjRBZyWFQ= @@ -422,22 +471,30 @@ github.com/shurcooL/sanitized_anchor_name v1.0.0/go.mod h1:1NzhyTcUVG4SuEtjjoZeV github.com/sirupsen/logrus v1.2.0/go.mod h1:LxeOpSwHxABJmUn/MG1IvRgCAasNZTLOkJPxbbu5VWo= github.com/sirupsen/logrus v1.4.2/go.mod h1:tLMulIdttU9McNUspp0xgXVQah82FyeX6MwdIuYE2rE= github.com/sirupsen/logrus v1.6.0/go.mod h1:7uNnSEd1DgxDLC74fIahvMZmmYsHGZGEOFrfsX/uA88= +github.com/sirupsen/logrus v1.7.0/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/sirupsen/logrus v1.8.1 h1:dJKuHgqk1NNQlqoA6BTlM1Wf9DOH3NBjQyu0h9+AZZE= github.com/sirupsen/logrus v1.8.1/go.mod h1:yWOB1SBYBC5VeMP7gHvWumXLIWorT60ONWic61uBYv0= github.com/smartystreets/assertions v0.0.0-20180927180507-b2de0cb4f26d/go.mod h1:OnSkiWE9lh6wB0YB77sQom3nweQdgAjqCqsofrRNTgc= github.com/smartystreets/goconvey v1.6.4/go.mod h1:syvi0/a8iFYH4r/RixwvyeAJjdLS9QV7WQ/tjFTllLA= +github.com/soheilhy/cmux v0.1.4/go.mod h1:IM3LyeVVIOuxMH7sFAkER9+bJ4dT7Ms6E4xg4kGIyLM= +github.com/soheilhy/cmux v0.1.5/go.mod h1:T7TcVDs9LWfQgPlPsdngu6I6QIoyIFZDDC6sNE1GqG0= github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= github.com/spaolacci/murmur3 v1.1.0 h1:7c1g84S4BPRrfL5Xrdp6fOJ206sU9y293DDHaoy0bLI= github.com/spaolacci/murmur3 v1.1.0/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA= +github.com/spf13/afero v1.1.2/go.mod h1:j4pytiNVoe2o6bmDsKpLACNPDBIoEAkihy7loJ1B0CQ= github.com/spf13/afero v1.2.2/go.mod h1:9ZxEEn6pIJ8Rxe320qSDBk6AsU0r9pR7Q4OcevTdifk= github.com/spf13/afero v1.6.0/go.mod h1:Ai8FlHk4v/PARR026UzYexafAt9roJ7LcLMAmO6Z93I= +github.com/spf13/cast v1.3.0/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= github.com/spf13/cast v1.3.1/go.mod h1:Qx5cxh0v+4UWYiBimWS+eyWzqEqokIECu5etghLkUJE= +github.com/spf13/cobra v1.1.3/go.mod h1:pGADOWyqRD/YMrPZigI/zbliZ2wVD/23d+is3pSWzOo= github.com/spf13/cobra v1.2.1/go.mod h1:ExllRjgxM/piMAM+3tAZvg8fsklGAf3tPfi+i8t68Nk= +github.com/spf13/jwalterweatherman v1.0.0/go.mod h1:cQK4TGJAtQXfYWX+Ddv3mKDzgVb68N+wFjFa4jdeBTo= github.com/spf13/jwalterweatherman v1.1.0/go.mod h1:aNWZUN0dPAAO/Ljvb5BEdw96iTZ0EXowPYD95IqWIGo= github.com/spf13/pflag v0.0.0-20170130214245-9ff6c6923cff/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.3/go.mod h1:DYY7MBk1bdzusC3SYhjObp+wFpr4gzcvqqNjLnInEg4= github.com/spf13/pflag v1.0.5 h1:iy+VFUOCP1a+8yFto/drg2CJ5u0yRoB7fZw3DKv/JXA= github.com/spf13/pflag v1.0.5/go.mod h1:McXfInJRrz4CZXVZOBLb0bTZqETkiAhM9Iw0y3An2Bg= +github.com/spf13/viper v1.7.0/go.mod h1:8WkrPz2fc9jxqZNCJI/76HCieCp4Q8HaLFoCha5qpdg= github.com/spf13/viper v1.8.1/go.mod h1:o0Pch8wJ9BVSWGQMbra6iw0oQ5oktSIBaujf1rJH9Ns= github.com/stoewer/go-strcase v1.2.0/go.mod h1:IBiWB2sKIp3wVVQ3Y035++gc+knqhUQag1KpM8ahLw8= github.com/stretchr/objx v0.1.0/go.mod h1:HFkY916IF+rwdDfMAkV7OtwuqBVzrE8GR6GFx+wExME= @@ -454,17 +511,26 @@ github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/ github.com/stretchr/testify v1.8.0 h1:pSgiaMZlXftHpm5L7V1+rVB+AZJydKsMxsQBIJw4PKk= github.com/stretchr/testify v1.8.0/go.mod h1:yNjHg4UonilssWZ8iaSj1OCr/vHnekPRkoO+kdMU+MU= github.com/subosito/gotenv v1.2.0/go.mod h1:N0PQaV/YGNqwC0u51sEeR/aUtSLEXKX9iv69rRypqCw= +github.com/tmc/grpc-websocket-proxy v0.0.0-20190109142713-0ad062ec5ee5/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= +github.com/tmc/grpc-websocket-proxy v0.0.0-20201229170055-e5319fda7802/go.mod h1:ncp9v5uamzpCO7NfCPTXjqaC+bZgJeR0sMTm6dMHP7U= github.com/xhit/go-str2duration/v2 v2.1.0 h1:lxklc02Drh6ynqX+DdPyp5pCKLUQpRT8bp8Ydu2Bstc= github.com/xhit/go-str2duration/v2 v2.1.0/go.mod h1:ohY8p+0f07DiV6Em5LKB0s2YpLtXVyJfNt1+BlmyAsU= +github.com/xiang90/probing v0.0.0-20190116061207-43a291ad63a2/go.mod h1:UETIi67q53MR2AWcXfiuqkDkRtnGDLqkBTpCHuJHxtU= github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74= github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k= +go.etcd.io/bbolt v1.3.2/go.mod h1:IbVyRI1SCnLcuJnV2u8VeU0CEYM7e686BmAb1XKL+uU= +go.etcd.io/bbolt v1.3.6/go.mod h1:qXsaaIqmgQH0T+OPdb99Bf+PKfBBQVAdyD6TY9G8XM4= go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs= go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g= go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ= +go.etcd.io/etcd/client/v3 v3.5.0/go.mod h1:AIKXXVX/DQXtfTEqBryiLTUXwON+GuvO6Z7lLS/oTh0= +go.etcd.io/etcd/pkg/v3 v3.5.0/go.mod h1:UzJGatBQ1lXChBkQF0AuAtkRQMYnHubxAEYIrC3MSsE= +go.etcd.io/etcd/raft/v3 v3.5.0/go.mod h1:UFOHSIvO/nKwd4lhkwabrTD3cqW5yVyYYf/KlD00Szc= +go.etcd.io/etcd/server/v3 v3.5.0/go.mod h1:3Ah5ruV+M+7RZr0+Y/5mNLwC+eQlni+mQmOVdCRJoS4= go.opencensus.io v0.21.0/go.mod h1:mSImk1erAIZhrmZN+AvHh14ztQfjbGwt4TtuofqLduU= go.opencensus.io v0.22.0/go.mod h1:+kGneAE2xo2IficOXnaByMWTGM9T73dGwxeWcUqIpI8= go.opencensus.io v0.22.2/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= @@ -473,6 +539,7 @@ go.opencensus.io v0.22.4/go.mod h1:yxeiOL68Rb0Xd1ddK5vPZ/oVn4vY4Ynel7k9FzqtOIw= go.opencensus.io v0.22.5/go.mod h1:5pWMHQbX5EPX2/62yrJeAkowc+lfs/XD7Uxpq3pI6kk= go.opencensus.io v0.23.0/go.mod h1:XItmlyltB5F7CS4xOC1DcqMoFqwtC6OG2xF7mCv7P7E= go.opentelemetry.io/contrib v0.20.0/go.mod h1:G/EtFaa6qaN7+LxqfIAT3GiZa7Wv5DTBUzl5H4LY0Kc= +go.opentelemetry.io/contrib/instrumentation/google.golang.org/grpc/otelgrpc v0.20.0/go.mod h1:oVGt1LRbBOBq1A5BQLlUg9UaU/54aiHw8cgjV3aWZ/E= go.opentelemetry.io/contrib/instrumentation/net/http/otelhttp v0.20.0/go.mod h1:2AboqHi0CiIZU0qwhtUfCYD1GeUzvvIXWNkhDt7ZMG4= go.opentelemetry.io/otel v0.20.0/go.mod h1:Y3ugLH2oa81t5QO+Lty+zXf8zC9L26ax4Nzoxm/dooo= go.opentelemetry.io/otel/exporters/otlp v0.20.0/go.mod h1:YIieizyaN77rtLJra0buKiNBOm9XQfkPEKBeuhoMwAM= @@ -483,11 +550,14 @@ go.opentelemetry.io/otel/sdk/export/metric v0.20.0/go.mod h1:h7RBNMsDJ5pmI1zExLi go.opentelemetry.io/otel/sdk/metric v0.20.0/go.mod h1:knxiS8Xd4E/N+ZqKmUPf3gTTZ4/0TjTXukfxjzSTpHE= go.opentelemetry.io/otel/trace v0.20.0/go.mod h1:6GjCW8zgDjwGHGa6GkyeB8+/5vjT16gUEi0Nf1iBdgw= go.opentelemetry.io/proto/otlp v0.7.0/go.mod h1:PqfVotwruBrMGOCsRd/89rSnXhoiJIqeYNgFYFoEGnI= +go.uber.org/atomic v1.4.0/go.mod h1:gD2HeocX3+yG+ygLZcrzQJaqmWj9AIm7n08wl/qW/PE= go.uber.org/atomic v1.7.0 h1:ADUqmZGgLDDfbSL9ZmPxKTybcoEYHgpYfELNoN+7hsw= go.uber.org/atomic v1.7.0/go.mod h1:fEN4uk6kAWBTFdckzkM89CLk9XfWZrxpCo0nPH17wJc= go.uber.org/goleak v1.1.10/go.mod h1:8a7PlsEVH3e/a/GLqe5IIrQx6GzcnRmZEufDUTk4A7A= +go.uber.org/multierr v1.1.0/go.mod h1:wR5kodmAFQ0UK8QlbwjlSNy0Z68gJhDJUG5sjR94q/0= go.uber.org/multierr v1.6.0 h1:y6IPFStTAIT5Ytl7/XYmHvzXQ7S3g/IeZW9hyZ5thw4= go.uber.org/multierr v1.6.0/go.mod h1:cdWPpRnG4AhwMwsgIHip0KRBQjJy5kYEpYjJxpXp9iU= +go.uber.org/zap v1.10.0/go.mod h1:vwi/ZaCAaUcBkycHslxD9B2zi4UTXhF60s6SWpuDF0Q= go.uber.org/zap v1.17.0/go.mod h1:MXVU+bhUf/A7Xi2HNOnopQOrmycQ5Ih87HtOu4q5SSo= go.uber.org/zap v1.19.0/go.mod h1:xg/QME4nWcxGxrpdeYfq7UvYrLh66cuVKdrbD1XF/NI= go.uber.org/zap v1.19.1 h1:ue41HOKd1vGURxrmeKIgELGb3jPW9DMUDGtsinblHwI= @@ -503,6 +573,7 @@ golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8U golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20201002170205-7f63de1d35b0/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto= golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= +golang.org/x/crypto v0.0.0-20210817164053-32db794688a5/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190306152737-a1d7652674e8/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/exp v0.0.0-20190510132918-efd6b22b2522/go.mod h1:ZjyILWgesfNpC6sMxTJOJm9Kp84zZh5NQWvqDGG3Qr8= @@ -546,6 +617,7 @@ golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73r golang.org/x/net v0.0.0-20181023162649-9b4f9f5ad519/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181114220301-adae6a3d119a/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20181201002055-351d144fa1fc/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= +golang.org/x/net v0.0.0-20181220203305-927f97764cc3/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190108225652-1e06a53dbb7e/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190213061140-3a22650c66bd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4= golang.org/x/net v0.0.0-20190311183353-d8887717615a/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg= @@ -576,6 +648,7 @@ golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81R golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201031054903-ff519b6c9102/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= +golang.org/x/net v0.0.0-20201202161906-c7110b5ffcbb/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU= golang.org/x/net v0.0.0-20201209123823-ac852fbbde11/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210119194325-5f4716e94777/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= @@ -620,6 +693,7 @@ golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5h golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181026203630-95b1ffbd15a5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= +golang.org/x/sys v0.0.0-20181107165924-66b7b1311ac8/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20190312061237-fead79001313/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -656,6 +730,7 @@ golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20200803210538-64077c9b5642/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200831180312-196b9ba8737a/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200905004654-be1d3432aa8f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= +golang.org/x/sys v0.0.0-20200923182605-d9f96fdee20d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201119102817-f84b799fce68/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20201201145000-ef89a241ccb3/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -672,6 +747,7 @@ golang.org/x/sys v0.0.0-20210403161142-5e06dd20ab57/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20210510120138-977fb7262007/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210603081109-ebe580a85c40/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210616094352-59db8d763f22/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210809222454-d867a43fc93e/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20210819135213-f52c844e1c1c/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= @@ -697,9 +773,12 @@ golang.org/x/text v0.16.0/go.mod h1:GhwF1Be+LQoKShO3cGOHzqOgRrGaYc9AvblQOmPVHnI= golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/time v0.0.0-20210220033141-f8bda1e9f3ba/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac h1:7zkz7BUtwNFFqcowJ+RIgu2MaV/MapERkDIy+mwPyjs= golang.org/x/time v0.0.0-20210723032227-1f47c861a9ac/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= +golang.org/x/tools v0.0.0-20180221164845-07fd8470d635/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= +golang.org/x/tools v0.0.0-20181030221726-6c7e314b6563/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190114222345-bf090417da8b/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ= golang.org/x/tools v0.0.0-20190226205152-f727befe758c/go.mod h1:9Yl7xja0Znq3iFh3HoIrodX9oNMXvdceNzlUR8zjMvY= golang.org/x/tools v0.0.0-20190311212946-11955173bddd/go.mod h1:LCzVGOaR6xXOjkQ3onu1FJEFr0SW1gC7cKk1uF8kGRs= @@ -813,6 +892,7 @@ google.golang.org/genproto v0.0.0-20200228133532-8c2c7df3a383/go.mod h1:55QSHmfG google.golang.org/genproto v0.0.0-20200305110556-506484158171/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200312145019-da6875a35672/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200331122359-1ee6d9798940/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= +google.golang.org/genproto v0.0.0-20200423170343-7949de9c1215/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200430143042-b979b6f78d84/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200511104702-f5ebc3bea380/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= google.golang.org/genproto v0.0.0-20200513103714-09dca8ec2884/go.mod h1:55QSHmfGQM9UVYDPBsyGGes0y52j32PQ3BqQfXhyH3c= @@ -824,6 +904,7 @@ google.golang.org/genproto v0.0.0-20200804131852-c06518451d9c/go.mod h1:FWY/as6D google.golang.org/genproto v0.0.0-20200825200019-8632dd797987/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20200904004341-0bd0a958aa1d/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201019141844-1ed22bb0c154/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= +google.golang.org/genproto v0.0.0-20201102152239-715cce707fb0/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201109203340-2640f1f9cdfb/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201201144952-b05cb90ed32e/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= google.golang.org/genproto v0.0.0-20201210142538-e3217bee35cc/go.mod h1:FWY/as6DDZQgahTzZj3fqbO1CbirC29ZNUFHwi0/+no= @@ -884,11 +965,15 @@ gopkg.in/errgo.v2 v2.1.0/go.mod h1:hNsd1EY+bozCKY1Ytp96fpM3vjJbqLJn88ws8XvfDNI= gopkg.in/fsnotify.v1 v1.4.7/go.mod h1:Tz8NjZHkW78fSQdbUxIjBTcgA1z1m8ZHf0WmKUhAMys= gopkg.in/inf.v0 v0.9.1 h1:73M5CoZyi3ZLMOyDlQh031Cx6N9NDJ2Vvfl76EDAgDc= gopkg.in/inf.v0 v0.9.1/go.mod h1:cWUDdTG/fYaXco+Dcufb5Vnc6Gp2YChqWtbxRZE0mXw= +gopkg.in/ini.v1 v1.51.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/ini.v1 v1.62.0/go.mod h1:pNLf8WUiyNEtQjuu5G5vTm06TEv9tsIgeAvK8hOrP4k= gopkg.in/natefinch/lumberjack.v2 v2.0.0/go.mod h1:l0ndWWf7gzL7RNwBG7wST/UCcT4T24xpD6X8LsfU/+k= +gopkg.in/resty.v1 v1.12.0/go.mod h1:mDo4pnntr5jdWRML875a/NmxYqAlA73dVijT2AXvQQo= +gopkg.in/square/go-jose.v2 v2.2.2/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/square/go-jose.v2 v2.4.1/go.mod h1:M9dMgbHiYLoDGQrXy7OpJDJWiKiU//h+vD76mk0e1AI= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7 h1:uRGJdciOHaEIrze2W8Q3AKkepLTh2hOroT7a+7czfdQ= gopkg.in/tomb.v1 v1.0.0-20141024135613-dd632973f1e7/go.mod h1:dt/ZhP58zS4L8KSrWDmTeBkI65Dw0HsyUHuEVlX15mw= +gopkg.in/yaml.v2 v2.0.0-20170812160011-eb3733d160e7/go.mod h1:JAlM8MvJe8wmxCU4Bli9HhUf9+ttbYbLASfIpnQbh74= gopkg.in/yaml.v2 v2.2.1/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= gopkg.in/yaml.v2 v2.2.3/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI= @@ -920,8 +1005,10 @@ k8s.io/apiextensions-apiserver v0.23.0/go.mod h1:xIFAEEDlAZgpVBl/1VSjGDmLoXAWRG4 k8s.io/apimachinery v0.22.4/go.mod h1:yU6oA6Gnax9RrxGzVvPFFJ+mpnW6PBSqp0sx0I0HHW0= k8s.io/apimachinery v0.23.0 h1:mIfWRMjBuMdolAWJ3Fd+aPTMv3X9z+waiARMpvvb0HQ= k8s.io/apimachinery v0.23.0/go.mod h1:fFCTTBKvKcwTPFzjlcxp91uPFZr+JA0FubU4fLzzFYc= +k8s.io/apiserver v0.23.0/go.mod h1:Cec35u/9zAepDPPFyT+UMrgqOCjgJ5qtfVJDxjZYmt4= k8s.io/client-go v0.22.4 h1:aAQ1Wk+I3bjCNk35YWUqbaueqrIonkfDPJSPDDe8Kfg= k8s.io/client-go v0.22.4/go.mod h1:Yzw4e5e7h1LNHA4uqnMVrpEpUs1hJOiuBsJKIlRCHDA= +k8s.io/code-generator v0.23.0/go.mod h1:vQvOhDXhuzqiVfM/YHp+dmg10WDZCchJVObc9MvowsE= k8s.io/component-base v0.23.0 h1:UAnyzjvVZ2ZR1lF35YwtNY6VMN94WtOnArcXBu34es8= k8s.io/component-base v0.23.0/go.mod h1:DHH5uiFvLC1edCpvcTDV++NKULdYYU6pR9Tt3HIKMKI= k8s.io/gengo v0.0.0-20200413195148-3a45101e95ac/go.mod h1:ezvh/TsK7cY6rbqRK0oQQ8IAqLxYwwyPxAX1Pzy0ii0= @@ -941,6 +1028,7 @@ k8s.io/utils v0.0.0-20210930125809-cb0fa318a74b/go.mod h1:jPW/WVKK9YHAvNhRxK0md/ rsc.io/binaryregexp v0.2.0/go.mod h1:qTv7/COck+e2FymRvadv62gMdZztPaShugOCi3I+8D8= rsc.io/quote/v3 v3.1.0/go.mod h1:yEA65RcK8LyAZtP9Kv3t0HmxON59tX3rD+tICJqUlj0= rsc.io/sampler v1.3.0/go.mod h1:T1hPZKmBbMNahiBKFy5HrXp6adAjACjK9JXDnKaTXpA= +sigs.k8s.io/apiserver-network-proxy/konnectivity-client v0.0.25/go.mod h1:Mlj9PNLmG9bZ6BHFwFKDo5afkpWyUISkb9Me0GnK66I= sigs.k8s.io/controller-runtime v0.11.0 h1:DqO+c8mywcZLFJWILq4iktoECTyn30Bkj0CwgqMpZWQ= sigs.k8s.io/controller-runtime v0.11.0/go.mod h1:KKwLiTooNGu+JmLZGn9Sl3Gjmfj66eMbCQznLP5zcqA= sigs.k8s.io/json v0.0.0-20211020170558-c049b76a60c6 h1:fD1pz4yfdADVNfFmcP2aBEtudwUQ1AlLnRBALr33v3s= diff --git a/tests/operator/operator_suite_test.go b/tests/operator/operator_suite_test.go index 7cd0bcfa..f1933a06 100644 --- a/tests/operator/operator_suite_test.go +++ b/tests/operator/operator_suite_test.go @@ -37,8 +37,7 @@ var ( namespaceName string = "default" k8sClient client.Client k8sConfig *rest.Config - brokerName string = "test-sn-platform" - proxyName string = "test-sn-platform" + brokerName string = "test-pulsar" proxyURL string = fmt.Sprintf("http://%s-broker.%s.svc.cluster.local:6650", brokerName, namespaceName) pulsarClient pulsar.Client ) diff --git a/tests/operator/resources_test.go b/tests/operator/resources_test.go index a57fc0c5..0061163c 100644 --- a/tests/operator/resources_test.go +++ b/tests/operator/resources_test.go @@ -74,6 +74,16 @@ var _ = Describe("Resources", func() { }, }, } + ppackage *v1alphav1.PulsarPackage + ppackageurl string = "function://public/default/api-examples@v3.2.3.3" + pfuncName string = "test-func" + psinkName string = "test-sink" + psourceName string = "test-source" + pfunc *v1alphav1.PulsarFunction + psinkpackageurl string = "builtin://data-generator" + psink *v1alphav1.PulsarSink + psource *v1alphav1.PulsarSource + psourcepackageurl string = "builtin://data-generator" ) BeforeEach(func() { @@ -94,7 +104,10 @@ var _ = Describe("Resources", func() { roles := []string{"ironman"} actions := []string{"produce", "consume", "functions"} ppermission = utils.MakePulsarPermission(namespaceName, ppermissionName, topicName, pconnName, v1alphav1.PulsarResourceTypeTopic, roles, actions, v1alphav1.CleanUpAfterDeletion) - + ppackage = utils.MakePulsarPackage(namespaceName, pfuncName, ppackageurl, pconnName, lifecyclePolicy) + pfunc = utils.MakePulsarFunction(namespaceName, pfuncName, ppackageurl, pconnName, lifecyclePolicy) + psink = utils.MakePulsarSink(namespaceName, psinkName, psinkpackageurl, pconnName, lifecyclePolicy) + psource = utils.MakePulsarSource(namespaceName, psourceName, psourcepackageurl, pconnName, lifecyclePolicy) }) Describe("Basic resource operations", Ordered, func() { @@ -110,19 +123,6 @@ var _ = Describe("Resources", func() { }, "600s", "100ms").Should(BeTrue()) }) }) - Context("Check pulsar proxy", func() { - It("should create the pulsar proxy successfully", func() { - Eventually(func() bool { - statefulset := &v1.StatefulSet{} - k8sClient.Get(ctx, types.NamespacedName{ - Name: proxyName + "-proxy", - Namespace: namespaceName, - }, statefulset) - return statefulset.Status.ReadyReplicas > 0 && statefulset.Status.ReadyReplicas == statefulset.Status.Replicas - }, "600s", "100ms").Should(BeTrue()) - }) - - }) Context("PulsarConnection operation", func() { It("should create the pulsarconnection successfully", func() { @@ -209,8 +209,8 @@ var _ = Describe("Resources", func() { updateTopicSchema(ctx, ptopicName2, exampleSchemaDef) Eventually(func(g Gomega) { - podName := fmt.Sprintf("%s-proxy-0", proxyName) - containerName := "pulsar-proxy" + podName := fmt.Sprintf("%s-broker-0", brokerName) + containerName := fmt.Sprintf("%s-broker", brokerName) stdout, _, err := utils.ExecInPod(k8sConfig, namespaceName, podName, containerName, "./bin/pulsarctl -s http://localhost:8080 --token=$PROXY_TOKEN schemas get "+ptopic.Spec.Name) g.Expect(err).Should(Succeed()) @@ -228,8 +228,8 @@ var _ = Describe("Resources", func() { }) It("should always update pulsar resource when enable AlwaysUpdatePulsarResource", func() { - podName := fmt.Sprintf("%s-proxy-0", proxyName) - containerName := "pulsar-proxy" + podName := fmt.Sprintf("%s-broker-0", brokerName) + containerName := fmt.Sprintf("%s-broker", brokerName) By("delete topic2 with pulsarctl") _, stderr, err := utils.ExecInPod(k8sConfig, namespaceName, podName, containerName, @@ -293,6 +293,68 @@ var _ = Describe("Resources", func() { }) }) + Context("PulsarFunction & PulsarPackage operation", func() { + It("should create the pulsarpackage successfully", func() { + err := k8sClient.Create(ctx, ppackage) + Expect(err == nil || apierrors.IsAlreadyExists(err)).Should(BeTrue()) + }) + + It("the package should be ready", func() { + Eventually(func() bool { + p := &v1alphav1.PulsarPackage{} + tns := types.NamespacedName{Namespace: namespaceName, Name: pfuncName} + Expect(k8sClient.Get(ctx, tns, p)).Should(Succeed()) + return v1alphav1.IsPulsarResourceReady(p) + }, "40s", "100ms").Should(BeTrue()) + }) + + It("should create the pulsarfunction successfully", func() { + err := k8sClient.Create(ctx, pfunc) + Expect(err == nil || apierrors.IsAlreadyExists(err)).Should(BeTrue()) + }) + + It("the function should be ready", func() { + Eventually(func() bool { + f := &v1alphav1.PulsarFunction{} + tns := types.NamespacedName{Namespace: namespaceName, Name: pfuncName} + Expect(k8sClient.Get(ctx, tns, f)).Should(Succeed()) + return v1alphav1.IsPulsarResourceReady(f) + }, "40s", "100ms").Should(BeTrue()) + }) + }) + + Context("PulsarSink operation", func() { + It("should create the pulsarsink successfully", func() { + err := k8sClient.Create(ctx, psink) + Expect(err == nil || apierrors.IsAlreadyExists(err)).Should(BeTrue()) + }) + + It("the sink should be ready", func() { + Eventually(func() bool { + s := &v1alphav1.PulsarSink{} + tns := types.NamespacedName{Namespace: namespaceName, Name: psinkName} + Expect(k8sClient.Get(ctx, tns, s)).Should(Succeed()) + return v1alphav1.IsPulsarResourceReady(s) + }, "40s", "100ms").Should(BeTrue()) + }) + }) + + Context("PulsarSource operation", func() { + It("should create the pulsarsource successfully", func() { + err := k8sClient.Create(ctx, psource) + Expect(err == nil || apierrors.IsAlreadyExists(err)).Should(BeTrue()) + }) + + It("the source should be ready", func() { + Eventually(func() bool { + s := &v1alphav1.PulsarSource{} + tns := types.NamespacedName{Namespace: namespaceName, Name: psourceName} + Expect(k8sClient.Get(ctx, tns, s)).Should(Succeed()) + return v1alphav1.IsPulsarResourceReady(s) + }, "40s", "100ms").Should(BeTrue()) + }) + }) + AfterAll(func() { Eventually(func(g Gomega) { t := &v1alphav1.PulsarTopic{} diff --git a/tests/utils/spec.go b/tests/utils/spec.go index ca0a2f4a..61196db6 100644 --- a/tests/utils/spec.go +++ b/tests/utils/spec.go @@ -15,9 +15,13 @@ package utils import ( + "encoding/json" + corev1 "k8s.io/api/core/v1" + v1 "k8s.io/apiextensions-apiserver/pkg/apis/apiextensions/v1" "k8s.io/apimachinery/pkg/api/resource" metav1 "k8s.io/apimachinery/pkg/apis/meta/v1" + "k8s.io/utils/pointer" "github.com/streamnative/pulsar-resources-operator/api/v1alpha1" rsutils "github.com/streamnative/pulsar-resources-operator/pkg/utils" @@ -115,3 +119,169 @@ func MakePulsarPermission(namespace, name, resourceName, connectionName string, }, } } + +// MakePulsarPackage will generate a object of PulsarPackage +func MakePulsarPackage(namespace, name, packageURL, connectionName string, policy v1alpha1.PulsarResourceLifeCyclePolicy) *v1alpha1.PulsarPackage { + return &v1alpha1.PulsarPackage{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + }, + Spec: v1alpha1.PulsarPackageSpec{ + ConnectionRef: corev1.LocalObjectReference{ + Name: connectionName, + }, + PackageURL: packageURL, + FileURL: "https://github.com/freeznet/pulsar-functions-api-examples/raw/main/api-examples-2.10.4.3.jar", + Description: "api-examples.jar", + LifecyclePolicy: policy, + }, + } +} + +// MakePulsarFunction will generate a object of PulsarFunction +func MakePulsarFunction(namespace, name, functionPackageUrl, connectionName string, policy v1alpha1.PulsarResourceLifeCyclePolicy) *v1alpha1.PulsarFunction { + return &v1alpha1.PulsarFunction{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + }, + Spec: v1alpha1.PulsarFunctionSpec{ + ConnectionRef: corev1.LocalObjectReference{ + Name: connectionName, + }, + LifecyclePolicy: policy, + Jar: &v1alpha1.PackageContentRef{URL: functionPackageUrl}, + Tenant: "public", + Namespace: "default", + Name: name, + Inputs: []string{"input"}, + Output: "output", + Parallelism: 1, + ProcessingGuarantees: "ATLEAST_ONCE", + ClassName: "org.apache.pulsar.functions.api.examples.ExclamationFunction", + SubName: "test-sub", + SubscriptionPosition: "Latest", + CleanupSubscription: true, + SkipToLatest: true, + ForwardSourceMessageProperty: true, + RetainKeyOrdering: true, + AutoAck: true, + MaxMessageRetries: pointer.Int(101), + DeadLetterTopic: "dl-topic", + LogTopic: "func-log", + TimeoutMs: pointer.Int64(6666), + Secrets: map[string]v1alpha1.SecretKeyRef{ + "SECRET1": { + "sectest", "hello", + }, + }, + CustomRuntimeOptions: getMapToJSON(map[string]interface{}{ + "env": map[string]string{ + "HELLO": "WORLD", + }, + }), + }, + } +} + +// MakePulsarSink will generate a object of PulsarSink +func MakePulsarSink(namespace, name, sinkPackageUrl, connectionName string, policy v1alpha1.PulsarResourceLifeCyclePolicy) *v1alpha1.PulsarSink { + return &v1alpha1.PulsarSink{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + }, + Spec: v1alpha1.PulsarSinkSpec{ + ConnectionRef: corev1.LocalObjectReference{ + Name: connectionName, + }, + LifecyclePolicy: policy, + Archive: &v1alpha1.PackageContentRef{URL: sinkPackageUrl}, + Tenant: "public", + Namespace: "default", + Name: name, + Inputs: []string{"sink-input"}, + Parallelism: 1, + ProcessingGuarantees: "EFFECTIVELY_ONCE", + CleanupSubscription: false, + SourceSubscriptionPosition: "Latest", + AutoAck: true, + ClassName: "org.apache.pulsar.io.datagenerator.DataGeneratorPrintSink", + Resources: &v1alpha1.Resources{ + CPU: "1", + RAM: 2048, + Disk: 102400, + }, + Secrets: map[string]v1alpha1.SecretKeyRef{ + "SECRET1": { + "sectest", "hello", + }, + }, + CustomRuntimeOptions: getMapToJSON(map[string]interface{}{ + "env": map[string]string{ + "HELLO": "WORLD", + }, + }), + }, + } +} + +func getPulsarSourceConfig() *v1.JSON { + c := map[string]interface{}{ + "sleepBetweenMessages": 1000, + } + bytes, err := json.Marshal(c) + if err != nil { + return nil + } + return &v1.JSON{Raw: bytes} +} + +func getMapToJSON(c map[string]interface{}) *v1.JSON { + bytes, err := json.Marshal(c) + if err != nil { + return nil + } + return &v1.JSON{Raw: bytes} +} + +// MakePulsarSource will generate a object of PulsarSource +func MakePulsarSource(namespace, name, sourcePackageUrl, connectionName string, policy v1alpha1.PulsarResourceLifeCyclePolicy) *v1alpha1.PulsarSource { + return &v1alpha1.PulsarSource{ + ObjectMeta: metav1.ObjectMeta{ + Namespace: namespace, + Name: name, + }, + Spec: v1alpha1.PulsarSourceSpec{ + ConnectionRef: corev1.LocalObjectReference{ + Name: connectionName, + }, + LifecyclePolicy: policy, + Archive: &v1alpha1.PackageContentRef{URL: sourcePackageUrl}, + Tenant: "public", + Namespace: "default", + Name: name, + TopicName: "sink-input", + Parallelism: 1, + ProcessingGuarantees: "EFFECTIVELY_ONCE", + ClassName: "org.apache.pulsar.io.datagenerator.DataGeneratorSource", + Configs: getPulsarSourceConfig(), + Resources: &v1alpha1.Resources{ + CPU: "1", + RAM: 512, + Disk: 102400, + }, + Secrets: map[string]v1alpha1.SecretKeyRef{ + "SECRET1": { + "sectest", "hello", + }, + }, + CustomRuntimeOptions: getMapToJSON(map[string]interface{}{ + "env": map[string]string{ + "HELLO": "WORLD", + }, + }), + }, + } +}